Skip to content

Commit a2f56fe

Browse files
authored
Merge pull request #19 from h4rkl/feat/styling
feat: add theming and design elements
2 parents c0bec8f + eb53a8b commit a2f56fe

File tree

16 files changed

+425
-71
lines changed

16 files changed

+425
-71
lines changed

packages/ui/components.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"$schema": "https://ui.shadcn.com/schema.json",
3+
"style": "default",
4+
"rsc": true,
5+
"tsx": true,
6+
"tailwind": {
7+
"config": "tailwind.config.js",
8+
"css": "src/app/globals.css",
9+
"baseColor": "neutral",
10+
"cssVariables": true,
11+
"prefix": ""
12+
},
13+
"aliases": {
14+
"components": "@/components",
15+
"utils": "@/lib/utils",
16+
"ui": "@/components/ui",
17+
"lib": "@/lib",
18+
"hooks": "@/hooks"
19+
},
20+
"iconLibrary": "lucide"
21+
}

packages/ui/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"dependencies": {
1414
"@mosaic/sdk": "workspace:*",
1515
"@radix-ui/react-dropdown-menu": "^2.0.6",
16-
"@radix-ui/react-slot": "^1.0.2",
16+
"@radix-ui/react-slot": "^1.2.3",
1717
"@solana/react": "^2.3.0",
1818
"@solana/signers": "^2.3.0",
1919
"@solana/wallet-adapter-base": "^0.9.27",
@@ -24,16 +24,16 @@
2424
"@wallet-standard/core": "^1.1.1",
2525
"@wallet-standard/react": "^1.0.1",
2626
"bs58": "^6.0.0",
27-
"class-variance-authority": "^0.7.0",
28-
"clsx": "^2.0.0",
27+
"class-variance-authority": "^0.7.1",
28+
"clsx": "^2.1.1",
2929
"gill": "^0.10.2",
3030
"gill-react": "^0.4.4",
3131
"lucide-react": "^0.294.0",
3232
"next": "15.4.5",
3333
"next-themes": "^0.2.1",
3434
"react": "^18.2.0",
3535
"react-dom": "^18.2.0",
36-
"tailwind-merge": "^2.0.0",
36+
"tailwind-merge": "^2.6.0",
3737
"tailwindcss-animate": "^1.0.7"
3838
},
3939
"devDependencies": {
Lines changed: 13 additions & 0 deletions
Loading

packages/ui/src/app/dashboard/manage/[address]/page.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { ArrowLeft, ExternalLink } from 'lucide-react';
66
import Link from 'next/link';
77
import { useParams } from 'next/navigation';
88
import { TokenDisplay } from '@/types/token';
9+
import { Loader } from '@/components/ui/loader';
910
import { findTokenByAddress } from '@/lib/token/tokenData';
1011
import { SelectedWalletAccountContext } from '@/context/SelectedWalletAccountContext';
1112
import { TokenOverview } from './components/TokenOverview';
@@ -137,7 +138,7 @@ function ManageTokenConnected({ address }: { address: string }) {
137138
<div className="flex-1 p-8">
138139
<div className="flex items-center justify-center h-64">
139140
<div className="text-center">
140-
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary mx-auto mb-4"></div>
141+
<Loader className="h-8 w-8 mx-auto mb-4" />
141142
<p className="text-muted-foreground">Loading token details...</p>
142143
</div>
143144
</div>

packages/ui/src/app/dashboard/page.tsx

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import {
1919
DropdownMenuTrigger,
2020
} from '@/components/ui/dropdown-menu';
2121
import { TokenDisplay } from '@/types/token';
22+
import { Badge } from '@/components/ui/badge';
23+
import { Loader } from '@/components/ui/loader';
2224
import { getAllTokens, getTokenCount } from '@/lib/token/tokenData';
2325
import { TokenStorage } from '@/lib/token/tokenStorage';
2426
import { SelectedWalletAccountContext } from '@/context/SelectedWalletAccountContext';
@@ -80,7 +82,7 @@ function DashboardConnected({ publicKey }: { publicKey: string }) {
8082
<div className="flex-1 p-8">
8183
<div className="flex items-center justify-center h-64">
8284
<div className="text-center">
83-
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary mx-auto mb-4"></div>
85+
<Loader className="h-8 w-8 mx-auto mb-4" />
8486
<p className="text-muted-foreground">Loading your tokens...</p>
8587
</div>
8688
</div>
@@ -201,9 +203,14 @@ function DashboardConnected({ publicKey }: { publicKey: string }) {
201203
<Coins className="h-6 w-6 text-primary mr-3" />
202204
<div>
203205
<CardTitle className="text-lg">
204-
{token.name || `Token ${index + 1}`}
206+
{token.name || `Token ${index + 1}`}{' '}
207+
<Badge
208+
className="ml-2 align-middle text-sm"
209+
variant="outline"
210+
>
211+
{token.symbol || 'TKN'}
212+
</Badge>
205213
</CardTitle>
206-
<CardDescription>{token.symbol || 'TKN'}</CardDescription>
207214
</div>
208215
</div>
209216
<DropdownMenu>
@@ -246,25 +253,27 @@ function DashboardConnected({ publicKey }: { publicKey: string }) {
246253
<div className="space-y-2 text-sm">
247254
<div className="flex justify-between">
248255
<span className="text-muted-foreground">Type:</span>
249-
<span className="font-medium">
256+
<span className="font-normal">
250257
{getTokenTypeLabel(token.type)}
251258
</span>
252259
</div>
253260
<div className="flex justify-between">
254261
<span className="text-muted-foreground">Supply:</span>
255-
<span>{token.supply || '0'}</span>
262+
<span className="font-normal">{token.supply || '0'}</span>
256263
</div>
257264
<div className="flex justify-between">
258265
<span className="text-muted-foreground">Decimals:</span>
259-
<span>{token.decimals || '6'}</span>
266+
<span className="font-normal">{token.decimals || '6'}</span>
260267
</div>
261268
<div className="flex justify-between">
262269
<span className="text-muted-foreground">Created:</span>
263-
<span>{formatDate(token.createdAt)}</span>
270+
<span className="font-normal">
271+
{formatDate(token.createdAt)}
272+
</span>
264273
</div>
265274
<div className="flex justify-between">
266275
<span className="text-muted-foreground">Status:</span>
267-
<span className="text-green-600">Active</span>
276+
<span className="text-green-600 font-normal">Active</span>
268277
</div>
269278
{token.extensions && token.extensions.length > 0 && (
270279
<div className="pt-2">

packages/ui/src/app/globals.css

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44

55
@layer base {
66
:root {
7-
--background: 0 0% 100%;
7+
--background: 222.2 100% 99.5%;
88
--foreground: 222.2 84% 4.9%;
99
--card: 0 0% 100%;
1010
--card-foreground: 222.2 84% 4.9%;
1111
--popover: 0 0% 100%;
1212
--popover-foreground: 222.2 84% 4.9%;
13-
--primary: 222.2 47.4% 11.2%;
14-
--primary-foreground: 210 40% 98%;
13+
--primary: 255 80% 40%;
14+
--primary-foreground: 255 0% 100%;
1515
--secondary: 210 40% 96%;
1616
--secondary-foreground: 222.2 47.4% 11.2%;
1717
--muted: 210 40% 96%;
@@ -24,17 +24,18 @@
2424
--input: 214.3 31.8% 91.4%;
2525
--ring: 222.2 84% 4.9%;
2626
--radius: 0.5rem;
27+
--mosaic-gradient-color: #000;
2728
}
2829

2930
.dark {
30-
--background: 222.2 84% 4.9%;
31+
--background: 222.2 84% 3%;
3132
--foreground: 210 40% 98%;
3233
--card: 222.2 84% 4.9%;
3334
--card-foreground: 210 40% 98%;
3435
--popover: 222.2 84% 4.9%;
3536
--popover-foreground: 210 40% 98%;
36-
--primary: 210 40% 98%;
37-
--primary-foreground: 222.2 47.4% 11.2%;
37+
--primary: 255 80% 55%;
38+
--primary-foreground: 255 0% 100%;
3839
--secondary: 217.2 32.6% 17.5%;
3940
--secondary-foreground: 210 40% 98%;
4041
--muted: 217.2 32.6% 17.5%;
@@ -46,14 +47,73 @@
4647
--border: 217.2 32.6% 17.5%;
4748
--input: 217.2 32.6% 17.5%;
4849
--ring: 212.7 26.8% 83.9%;
50+
--mosaic-gradient-color: #fff;
4951
}
5052
}
5153

5254
@layer base {
5355
* {
5456
@apply border-border;
5557
}
58+
5659
body {
5760
@apply bg-background text-foreground;
61+
font-family: var(--font-sans), sans-serif;
62+
font-weight: 300;
63+
}
64+
65+
input,
66+
textarea,
67+
select {
68+
@apply px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent bg-card text-foreground;
69+
transition:
70+
box-shadow 0.2s,
71+
border-color 0.2s;
72+
}
73+
74+
input:disabled,
75+
textarea:disabled,
76+
select:disabled {
77+
@apply bg-muted text-muted-foreground cursor-not-allowed opacity-70;
78+
}
79+
80+
label {
81+
@apply block text-sm font-medium mb-2;
5882
}
83+
84+
button {
85+
@apply px-4 py-2 rounded-md font-medium focus:outline-none focus:ring-2 focus:ring-primary;
86+
transition:
87+
background 0.2s,
88+
color 0.2s;
89+
}
90+
}
91+
92+
.mosaic-text {
93+
position: relative;
94+
z-index: 1;
95+
background-image: radial-gradient(
96+
circle,
97+
var(--mosaic-gradient-color) 55%,
98+
transparent 0%
99+
);
100+
background-size: 2px 3px;
101+
background-position: 0px 1px;
102+
background-repeat: repeat;
103+
background-clip: text;
104+
color: transparent;
105+
}
106+
107+
.mosaic-text::before {
108+
content: '';
109+
position: absolute;
110+
inset: -5%;
111+
z-index: -1;
112+
border-radius: 9999px;
113+
background:
114+
radial-gradient(circle at 30% 40%, #1fff9a 0%, transparent 70%),
115+
radial-gradient(circle at 70% 60%, #9945ff 0%, transparent 70%);
116+
filter: blur(20px);
117+
opacity: 0.3;
118+
pointer-events: none;
59119
}

packages/ui/src/app/layout.tsx

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,25 @@
11
import type { Metadata } from 'next';
2-
import { AR_One_Sans } from 'next/font/google';
2+
import { Inter, Fira_Mono } from 'next/font/google';
33
import './globals.css';
44
import { ThemeProvider } from '@/components/theme-provider';
55
import { Header } from '@/components/layout/header';
66
import { Footer } from '@/components/layout/footer';
7+
import { SolanaProvider } from '@/components/solana-provider';
8+
import { cn } from '@/lib/utils';
79
import { ChainContextProvider } from '@/context/ChainContextProvider';
810
import { SelectedWalletAccountContextProvider } from '@/context/SelectedWalletAccountContextProvider';
911
import { RpcContextProvider } from '@/context/RpcContextProvider';
1012

11-
const ar = AR_One_Sans({ subsets: ['latin'] });
13+
const fontSans = Inter({
14+
subsets: ['latin'],
15+
weight: ['300', '500', '700'],
16+
variable: '--font-sans',
17+
});
18+
const fontMono = Fira_Mono({
19+
subsets: ['latin'],
20+
weight: ['400', '500', '700'],
21+
variable: '--font-mono',
22+
});
1223

1324
export const metadata: Metadata = {
1425
title: 'Mosaic - Tokenization Engine',
@@ -22,27 +33,35 @@ export default function RootLayout({
2233
children: React.ReactNode;
2334
}) {
2435
return (
25-
<html lang="en" suppressHydrationWarning>
26-
<body className={ar.className}>
27-
<ThemeProvider
28-
attribute="class"
29-
defaultTheme="dark"
30-
enableSystem
31-
disableTransitionOnChange
36+
<SolanaProvider>
37+
<html lang="en" suppressHydrationWarning>
38+
<body
39+
className={cn(
40+
fontSans.variable,
41+
fontMono.variable,
42+
'font-sans antialiased'
43+
)}
3244
>
33-
<ChainContextProvider>
34-
<SelectedWalletAccountContextProvider>
35-
<RpcContextProvider>
36-
<div className="flex min-h-screen flex-col bg-background">
37-
<Header />
38-
<main className="flex-1">{children}</main>
39-
<Footer />
40-
</div>
41-
</RpcContextProvider>
42-
</SelectedWalletAccountContextProvider>
43-
</ChainContextProvider>
44-
</ThemeProvider>
45-
</body>
46-
</html>
45+
<ThemeProvider
46+
attribute="class"
47+
defaultTheme="dark"
48+
enableSystem
49+
disableTransitionOnChange
50+
>
51+
<ChainContextProvider>
52+
<SelectedWalletAccountContextProvider>
53+
<RpcContextProvider>
54+
<div className="flex min-h-screen flex-col bg-background">
55+
<Header />
56+
<main className="flex-1">{children}</main>
57+
<Footer />
58+
</div>
59+
</RpcContextProvider>
60+
</SelectedWalletAccountContextProvider>
61+
</ChainContextProvider>
62+
</ThemeProvider>
63+
</body>
64+
</html>
65+
</SolanaProvider>
4766
);
4867
}

packages/ui/src/components/layout/footer.tsx

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,48 @@
1+
import { GithubIcon, TwitterIcon } from 'lucide-react';
2+
13
export function Footer() {
24
return (
35
<footer className="border-t bg-background">
4-
<div className="container flex h-16 items-center justify-center">
6+
<div className="container flex h-16 items-center justify-between">
57
<p className="text-sm text-muted-foreground">
6-
© 2025 Mosaic. All rights reserved.
8+
<a
9+
href="https://github.com/YOUR_ORG/mosaic/blob/main/LICENSE"
10+
className="underline hover:text-primary"
11+
target="_blank"
12+
rel="noopener noreferrer"
13+
>
14+
MIT License
15+
</a>
716
</p>
17+
<div className="flex gap-4 text-muted-foreground">
18+
<a
19+
href="https://github.com/gitteri/mosaic"
20+
target="_blank"
21+
rel="noopener noreferrer"
22+
aria-label="GitHub"
23+
className="hover:text-primary"
24+
>
25+
<GithubIcon className="w-5 h-5" />
26+
</a>
27+
<a
28+
href="https://x.com/solana"
29+
target="_blank"
30+
rel="noopener noreferrer"
31+
aria-label="Twitter"
32+
className="hover:text-primary"
33+
>
34+
<TwitterIcon className="w-5 h-5" />
35+
</a>
36+
<a
37+
href="https://solana.com"
38+
target="_blank"
39+
rel="noopener noreferrer"
40+
aria-label="Solana"
41+
className="hover:text-primary"
42+
>
43+
<img src="/solanaLogoMark.svg" alt="Solana" className="w-5 h-5" />
44+
</a>
45+
</div>
846
</div>
947
</footer>
1048
);

0 commit comments

Comments
 (0)