Skip to content

Commit 1c56e0d

Browse files
authored
Merge pull request #163 from emdevelopa/main
feat: added #129 Epic: Production ready wallet integrations
2 parents 1c9de98 + 786fe26 commit 1c56e0d

12 files changed

Lines changed: 1096 additions & 8283 deletions

File tree

backend/package-lock.json

Lines changed: 0 additions & 1541 deletions
This file was deleted.

frontend/app/globals.css

Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,6 +1283,277 @@ body {
12831283
}
12841284
}
12851285

1286+
/* ── Wallet Modal ─────────────────────────────────────────────────────────── */
1287+
1288+
.wallet-modal-backdrop {
1289+
position: fixed;
1290+
inset: 0;
1291+
z-index: 200;
1292+
background: rgba(2, 6, 23, 0.72);
1293+
backdrop-filter: blur(6px);
1294+
display: grid;
1295+
place-items: center;
1296+
padding: 1rem;
1297+
animation: fade-in 180ms ease-out;
1298+
}
1299+
1300+
.wallet-modal {
1301+
width: min(860px, 100%);
1302+
border-radius: 1.55rem;
1303+
border: 1px solid var(--surface-border);
1304+
background: var(--surface);
1305+
box-shadow: 0 30px 70px rgba(13, 48, 90, 0.22);
1306+
backdrop-filter: blur(12px);
1307+
padding: clamp(1.25rem, 2.8vw, 2.5rem);
1308+
animation: panel-rise 400ms cubic-bezier(0.16, 1, 0.3, 1);
1309+
}
1310+
1311+
.wallet-modal__header {
1312+
display: flex;
1313+
justify-content: space-between;
1314+
align-items: flex-start;
1315+
gap: 1rem;
1316+
margin-bottom: 1.25rem;
1317+
}
1318+
1319+
.wallet-modal__header h2 {
1320+
margin: 0.5rem 0 0;
1321+
font-size: clamp(1.4rem, 2.5vw, 2rem);
1322+
line-height: 1.12;
1323+
}
1324+
1325+
.wallet-modal__close {
1326+
flex-shrink: 0;
1327+
width: 2.2rem;
1328+
height: 2.2rem;
1329+
border: 1px solid rgba(19, 38, 61, 0.14);
1330+
border-radius: 0.6rem;
1331+
background: rgba(255, 255, 255, 0.7);
1332+
color: var(--text-muted);
1333+
font-size: 0.95rem;
1334+
cursor: pointer;
1335+
display: flex;
1336+
align-items: center;
1337+
justify-content: center;
1338+
transition: background 160ms;
1339+
}
1340+
1341+
.wallet-modal__close:hover:not(:disabled) {
1342+
background: rgba(255, 255, 255, 0.95);
1343+
color: var(--text-main);
1344+
}
1345+
1346+
.wallet-modal__close:disabled {
1347+
opacity: 0.55;
1348+
cursor: not-allowed;
1349+
}
1350+
1351+
/* Wallet card notes */
1352+
.wallet-card__note {
1353+
margin: -0.35rem 0 0;
1354+
font-size: 0.8rem !important;
1355+
color: var(--accent-strong) !important;
1356+
font-style: italic;
1357+
}
1358+
1359+
/* Install link variant of the wallet button */
1360+
.wallet-button--install {
1361+
display: flex;
1362+
align-items: center;
1363+
justify-content: center;
1364+
text-decoration: none;
1365+
background: linear-gradient(90deg, #1a6480, var(--wallet-accent));
1366+
font-size: 0.9rem;
1367+
}
1368+
1369+
/* Spinner row inside connecting button */
1370+
.wallet-button__spinner-row {
1371+
display: flex;
1372+
align-items: center;
1373+
justify-content: center;
1374+
gap: 0.55rem;
1375+
}
1376+
1377+
.wallet-button__spinner {
1378+
width: 0.82rem;
1379+
height: 0.82rem;
1380+
border-radius: 999px;
1381+
border: 2px solid rgba(255, 255, 255, 0.3);
1382+
border-top-color: #fff;
1383+
animation: spin 700ms linear infinite;
1384+
display: inline-block;
1385+
}
1386+
1387+
/* Card unavailable state (e.g. Freighter not installed) */
1388+
.wallet-card[data-unavailable="true"] {
1389+
opacity: 0.72;
1390+
}
1391+
1392+
/* ── WalletButton ─────────────────────────────────────────────────────────── */
1393+
1394+
.wallet-connect-btn {
1395+
display: inline-flex;
1396+
align-items: center;
1397+
justify-content: center;
1398+
height: 2.4rem;
1399+
padding: 0 1.15rem;
1400+
border: 0;
1401+
border-radius: 999px;
1402+
background: linear-gradient(90deg, var(--accent-strong), var(--wallet-accent));
1403+
color: #fff;
1404+
font-size: 0.92rem;
1405+
font-weight: 600;
1406+
cursor: pointer;
1407+
transition: filter 180ms ease, transform 140ms ease, box-shadow 180ms ease;
1408+
box-shadow: 0 4px 14px rgba(15, 122, 153, 0.28);
1409+
}
1410+
1411+
.wallet-connect-btn:hover {
1412+
filter: brightness(1.08);
1413+
transform: translateY(-1px);
1414+
box-shadow: 0 8px 20px rgba(15, 122, 153, 0.35);
1415+
}
1416+
1417+
.wallet-connect-btn:active {
1418+
transform: translateY(0);
1419+
}
1420+
1421+
.wallet-btn-skeleton {
1422+
width: 140px;
1423+
height: 2.4rem;
1424+
border-radius: 999px;
1425+
background: rgba(19, 38, 61, 0.1);
1426+
animation: pulse 920ms ease-in-out infinite alternate;
1427+
}
1428+
1429+
.wallet-btn-connecting {
1430+
display: inline-flex;
1431+
align-items: center;
1432+
gap: 0.55rem;
1433+
height: 2.4rem;
1434+
padding: 0 1rem;
1435+
border-radius: 999px;
1436+
background: rgba(15, 122, 153, 0.14);
1437+
color: var(--accent-strong);
1438+
font-size: 0.88rem;
1439+
font-weight: 600;
1440+
}
1441+
1442+
.wallet-status-spinner {
1443+
width: 0.82rem;
1444+
height: 0.82rem;
1445+
border-radius: 999px;
1446+
border: 2px solid rgba(13, 83, 120, 0.22);
1447+
border-top-color: var(--accent-strong);
1448+
animation: spin 700ms linear infinite;
1449+
}
1450+
1451+
/* Connected chip wrapper (positions dropdown) */
1452+
.wallet-chip-wrapper {
1453+
position: relative;
1454+
}
1455+
1456+
/* Network mismatch badge state */
1457+
.wallet-chip__network[data-mismatch="true"] {
1458+
background: rgba(177, 47, 63, 0.14);
1459+
color: var(--danger);
1460+
}
1461+
1462+
/* ── Wallet Dropdown ──────────────────────────────────────────────────────── */
1463+
1464+
.wallet-dropdown {
1465+
position: absolute;
1466+
top: calc(100% + 0.5rem);
1467+
right: 0;
1468+
min-width: 240px;
1469+
border-radius: 1rem;
1470+
border: 1px solid rgba(19, 38, 61, 0.14);
1471+
background: rgba(255, 255, 255, 0.96);
1472+
box-shadow: 0 14px 36px rgba(13, 48, 90, 0.18);
1473+
padding: 0.75rem;
1474+
display: flex;
1475+
flex-direction: column;
1476+
gap: 0.55rem;
1477+
animation: slide-down 180ms ease-out;
1478+
z-index: 201;
1479+
}
1480+
1481+
.wallet-dropdown__key {
1482+
display: flex;
1483+
align-items: center;
1484+
justify-content: space-between;
1485+
gap: 0.5rem;
1486+
border: 1px solid rgba(19, 38, 61, 0.1);
1487+
border-radius: 0.65rem;
1488+
padding: 0.55rem 0.7rem;
1489+
background: rgba(255, 255, 255, 0.6);
1490+
}
1491+
1492+
.wallet-dropdown__key code {
1493+
font-family: var(--font-mono), "IBM Plex Mono", monospace;
1494+
font-size: 0.8rem;
1495+
color: #183355;
1496+
overflow: hidden;
1497+
text-overflow: ellipsis;
1498+
white-space: nowrap;
1499+
max-width: 160px;
1500+
}
1501+
1502+
.wallet-dropdown__copy {
1503+
flex-shrink: 0;
1504+
border: 0;
1505+
background: transparent;
1506+
color: var(--accent-strong);
1507+
font-size: 0.8rem;
1508+
font-weight: 600;
1509+
cursor: pointer;
1510+
padding: 0.15rem 0.3rem;
1511+
border-radius: 0.4rem;
1512+
transition: background 140ms;
1513+
}
1514+
1515+
.wallet-dropdown__copy:hover {
1516+
background: rgba(13, 83, 120, 0.1);
1517+
}
1518+
1519+
.wallet-dropdown__warning {
1520+
margin: 0;
1521+
font-size: 0.8rem;
1522+
color: #8c2230;
1523+
background: rgba(255, 243, 245, 0.9);
1524+
border: 1px solid rgba(177, 47, 63, 0.24);
1525+
border-radius: 0.65rem;
1526+
padding: 0.45rem 0.6rem;
1527+
line-height: 1.4;
1528+
}
1529+
1530+
.wallet-dropdown__disconnect {
1531+
border: 1px solid rgba(19, 38, 61, 0.16);
1532+
border-radius: 0.7rem;
1533+
height: 2.1rem;
1534+
background: rgba(255, 255, 255, 0.8);
1535+
color: var(--danger);
1536+
font-size: 0.88rem;
1537+
font-weight: 600;
1538+
cursor: pointer;
1539+
transition: background 140ms;
1540+
}
1541+
1542+
.wallet-dropdown__disconnect:hover {
1543+
background: rgba(177, 47, 63, 0.06);
1544+
}
1545+
1546+
@media (max-width: 640px) {
1547+
.wallet-dropdown {
1548+
right: auto;
1549+
left: 0;
1550+
}
1551+
1552+
.wallet-modal {
1553+
border-radius: 1.15rem;
1554+
}
1555+
}
1556+
12861557
.dashboard-loading-state,
12871558
.dashboard-error-state {
12881559
display: flex;

frontend/components/Navbar.tsx

Lines changed: 49 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,54 @@
1-
import React from 'react';
2-
import { Button } from './ui/Button';
3-
import { ModeToggle } from './ModeToggle';
1+
import React from "react";
2+
import { Button } from "./ui/Button";
3+
import { ModeToggle } from "./ModeToggle";
4+
import { WalletButton } from "./wallet/WalletButton";
45

56
export const Navbar = () => {
6-
return (
7-
<nav className="sticky top-0 z-50 flex items-center justify-between px-6 py-4 backdrop-blur-md md:px-12 border-b border-glass-border bg-background/50">
8-
<div className="flex items-center gap-2">
9-
<div className="h-9 w-9 rounded-xl bg-accent flex items-center justify-center shadow-[0_0_15px_rgba(16,185,129,0.2)]">
10-
<svg className="h-6 w-6 text-background" fill="none" stroke="currentColor" viewBox="0 0 24 24">
11-
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
12-
</svg>
13-
</div>
14-
<span className="text-2xl font-black tracking-tighter text-white">FlowFi</span>
15-
</div>
7+
return (
8+
<nav className="sticky top-0 z-50 flex items-center justify-between px-6 py-4 backdrop-blur-md md:px-12 border-b border-glass-border bg-background/50">
9+
<div className="flex items-center gap-2">
10+
<div className="h-9 w-9 rounded-xl bg-accent flex items-center justify-center shadow-[0_0_15px_rgba(16,185,129,0.2)]">
11+
<svg
12+
className="h-6 w-6 text-background"
13+
fill="none"
14+
stroke="currentColor"
15+
viewBox="0 0 24 24"
16+
>
17+
<path
18+
strokeLinecap="round"
19+
strokeLinejoin="round"
20+
strokeWidth="2"
21+
d="M13 10V3L4 14h7v7l9-11h-7z"
22+
/>
23+
</svg>
24+
</div>
25+
<span className="text-2xl font-black tracking-tighter text-white">
26+
FlowFi
27+
</span>
28+
</div>
1629

17-
<div className="hidden items-center gap-8 text-sm font-semibold text-slate-400 md:flex">
18-
<a href="#features" className="transition-colors hover:text-accent">Features</a>
19-
<a href="#how-it-works" className="transition-colors hover:text-accent">Process</a>
20-
<a href="#faq" className="transition-colors hover:text-accent">FAQ</a>
21-
<a href="#" className="transition-colors hover:text-accent">Ecosystem</a>
22-
<ModeToggle />
23-
</div>
30+
<div className="hidden items-center gap-8 text-sm font-semibold text-slate-400 md:flex">
31+
<a href="#features" className="transition-colors hover:text-accent">
32+
Features
33+
</a>
34+
<a href="#how-it-works" className="transition-colors hover:text-accent">
35+
Process
36+
</a>
37+
<a href="#faq" className="transition-colors hover:text-accent">
38+
FAQ
39+
</a>
40+
<a href="#" className="transition-colors hover:text-accent">
41+
Ecosystem
42+
</a>
43+
<ModeToggle />
44+
</div>
2445

25-
<div className="flex items-center gap-4">
26-
<Button variant="ghost" className="hidden sm:inline-flex">Log In</Button>
27-
<Button variant="primary" glow size="md">
28-
Connect Wallet
29-
</Button>
30-
</div>
31-
</nav>
32-
);
46+
<div className="flex items-center gap-4">
47+
<Button variant="ghost" className="hidden sm:inline-flex">
48+
Log In
49+
</Button>
50+
<WalletButton />
51+
</div>
52+
</nav>
53+
);
3354
};

0 commit comments

Comments
 (0)