From dcfe9cfa9a11da9d4c80636ef09ce386be065df0 Mon Sep 17 00:00:00 2001 From: Fale1278 Date: Sun, 29 Mar 2026 12:56:33 -0700 Subject: [PATCH] implemented fixes and solved issues --- frontend/app/dashboard/layout.tsx | 42 +++++-- frontend/app/dashboard/output.txt | 9 ++ frontend/app/dashboard/page.tsx | 117 ++++++------------- frontend/app/dashboard/payments/page.tsx | 96 ++++----------- frontend/app/dashboard/projects/page.tsx | 52 +++------ frontend/app/output.txt | 14 +++ frontend/components/layout/Header.tsx | 24 +++- frontend/components/layout/Sidebar.tsx | 142 ++++++----------------- frontend/components/layout/output.txt | 7 ++ frontend/output.txt | 23 ++++ 10 files changed, 212 insertions(+), 314 deletions(-) create mode 100644 frontend/app/dashboard/output.txt create mode 100644 frontend/app/output.txt create mode 100644 frontend/components/layout/output.txt create mode 100644 frontend/output.txt diff --git a/frontend/app/dashboard/layout.tsx b/frontend/app/dashboard/layout.tsx index 9520916..184faea 100644 --- a/frontend/app/dashboard/layout.tsx +++ b/frontend/app/dashboard/layout.tsx @@ -1,10 +1,9 @@ 'use client'; -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { useAuthStore } from '@/store/useAuthStore'; import { usePathname, useRouter } from 'next/navigation'; -import { useEffect } from 'react'; -import { Sidebar } from '@/components/layout/Sidebar'; +import Sidebar from '@/components/layout/Sidebar'; import { Header } from '@/components/layout/Header'; import { ErrorBoundary } from '@/components/errors/ErrorBoundary'; @@ -17,6 +16,18 @@ export default function DashboardLayout({ const router = useRouter(); const pathname = usePathname(); + /* ================================ + ✅ STEP 1: SIDEBAR STATE (NEW) + ================================= */ + const [sidebarOpen, setSidebarOpen] = useState(false); + + const toggleSidebar = () => { + setSidebarOpen((prev) => !prev); + }; + + /* ================================ + EXISTING SCROLL LOGIC (UNCHANGED) + ================================= */ const mainRef = React.useRef(null); const scrollPositions = React.useRef>({}); @@ -26,7 +37,7 @@ export default function DashboardLayout({ } }, [isAuthenticated, router]); - // Save scroll position when leaving a page + // Save scroll position useEffect(() => { const main = mainRef.current; if (!main) return; @@ -39,10 +50,11 @@ export default function DashboardLayout({ return () => main.removeEventListener('scroll', handleScroll); }, [pathname]); - // Restore scroll position when arriving at a page + // Restore scroll position useEffect(() => { const main = mainRef.current; if (!main) return; + const saved = scrollPositions.current[pathname]; main.scrollTop = saved ?? 0; }, [pathname]); @@ -52,11 +64,21 @@ export default function DashboardLayout({ } return ( -
- -
-
-
+
+ {/* ✅ Sidebar now controlled */} + + +
+ {/* ✅ Header can open sidebar */} +
+ +
{children} diff --git a/frontend/app/dashboard/output.txt b/frontend/app/dashboard/output.txt new file mode 100644 index 0000000..b3f7d85 --- /dev/null +++ b/frontend/app/dashboard/output.txt @@ -0,0 +1,9 @@ +C:\Users\USER\Desktop\KING\Clones\agenticpay\frontend\app\dashboard +├── invoices +├── layout.tsx +├── page.tsx +├── payments +└── projects + +directory: 3 file: 2 + diff --git a/frontend/app/dashboard/page.tsx b/frontend/app/dashboard/page.tsx index ce6f5f3..9065399 100644 --- a/frontend/app/dashboard/page.tsx +++ b/frontend/app/dashboard/page.tsx @@ -17,7 +17,6 @@ export default function DashboardPage() {

Welcome back! Here's your overview.

- {/* Simplified Loading for Recent Activity */} Recent Activity @@ -43,84 +42,39 @@ export default function DashboardPage() { {/* Stats Grid */}
- - - - - Total Earnings - - - - -
{stats.totalEarnings}
-

- - All time -

-
-
-
- - - - - - Pending Payments - - - - -
{stats.pendingPayments}
-

Awaiting approval

-
-
-
- - - - - - Active Projects - - - - -
{stats.activeProjects}
-

In progress

-
-
-
- - - - - - Completed - - - - -
{stats.completedProjects}
-

Projects done

-
-
-
+ {[{ + title: 'Total Earnings', icon: , value: stats.totalEarnings, subtitle: 'All time', color: 'text-green-600', extraIcon: + }, { + title: 'Pending Payments', icon: , value: stats.pendingPayments, subtitle: 'Awaiting approval', color: 'text-yellow-600' + }, { + title: 'Active Projects', icon: , value: stats.activeProjects, subtitle: 'In progress', color: 'text-blue-600' + }, { + title: 'Completed', icon: , value: stats.completedProjects, subtitle: 'Projects done', color: 'text-gray-600' + }].map((stat, idx) => ( + + + + {stat.title} + {stat.icon} + + +
{stat.value}
+ {stat.extraIcon ? ( +

+ {stat.extraIcon} {stat.subtitle} +

+ ) : ( +

{stat.subtitle}

+ )} +
+
+
+ ))}
{/* Recent Activity */} @@ -137,7 +91,7 @@ export default function DashboardPage() { {recentActivity.length === 0 ? (

No recent activity found.

) : ( -
+
{recentActivity.map((activity, idx) => (
@@ -155,5 +109,4 @@ export default function DashboardPage() {
); -} - +} \ No newline at end of file diff --git a/frontend/app/dashboard/payments/page.tsx b/frontend/app/dashboard/payments/page.tsx index 21ecd60..d01a971 100644 --- a/frontend/app/dashboard/payments/page.tsx +++ b/frontend/app/dashboard/payments/page.tsx @@ -4,15 +4,7 @@ import { useState } from 'react'; import { useDashboardData } from '@/lib/hooks/useDashboardData'; import { useAuthStore } from '@/store/useAuthStore'; import { Card, CardContent } from '@/components/ui/card'; -import { - CheckCircle2, - Clock, - XCircle, - ExternalLink, - Wallet, - QrCode, - Loader2, -} from 'lucide-react'; +import { CheckCircle2, Clock, XCircle, ExternalLink, Wallet, QrCode, Loader2 } from 'lucide-react'; import { motion } from 'framer-motion'; import { PaymentCardSkeleton } from '@/components/ui/loading-skeletons'; import { EmptyState } from '@/components/empty/EmptyState'; @@ -25,20 +17,15 @@ export default function PaymentsPage() { const router = useRouter(); const { payments, loading } = useDashboardData(); const timezone = useAuthStore((state) => state.timezone); - const [isQrModalOpen, setIsQrModalOpen] = useState(false); const address = useAuthStore((state) => state.address); const getStatusIcon = (status: string) => { switch (status) { - case 'completed': - return ; - case 'pending': - return ; - case 'failed': - return ; - default: - return null; + case 'completed': return ; + case 'pending': return ; + case 'failed': return ; + default: return null; } }; @@ -46,19 +33,13 @@ export default function PaymentsPage() { return (
-

- Payment History -

-

- View all your payment transactions -

+

Payment History

+

View all your payment transactions

- Loading payments...
- -
+
{[1, 2, 3, 4].map((i) => ( ))} @@ -72,26 +53,18 @@ export default function PaymentsPage() { {/* Header */}
-

- Payment History -

-

- View all your payment transactions -

+

Payment History

+

View all your payment transactions

{address && ( - )}
- {/* Content */} + {/* Payments Grid */} {payments.length === 0 ? ( @@ -99,15 +72,12 @@ export default function PaymentsPage() { icon={Wallet} title="No payments yet" description="Your payment history will appear here once you receive payments for completed projects." - action={{ - label: 'View Projects', - onClick: () => router.push('/dashboard/projects'), - }} + action={{ label: 'View Projects', onClick: () => router.push('/dashboard/projects') }} /> ) : ( -
+
{payments.map((payment, index) => (
{getStatusIcon(payment.status)} -
-

- {payment.projectTitle} -

- +

{payment.projectTitle}

- {payment.type === 'milestone_payment' - ? 'Milestone Payment' - : 'Full Payment'} + {payment.type === 'milestone_payment' ? 'Milestone Payment' : 'Full Payment'}

-

- {formatDateTimeInTimeZone( - payment.timestamp, - timezone - )} + {formatDateTimeInTimeZone(payment.timestamp, timezone)}

@@ -147,12 +107,8 @@ export default function PaymentsPage() {

{payment.transactionHash && ( - + View on Explorer @@ -162,9 +118,7 @@ export default function PaymentsPage() { {payment.transactionHash && (
-

- {payment.transactionHash} -

+

{payment.transactionHash}

)} @@ -175,13 +129,7 @@ export default function PaymentsPage() { )} {/* QR Modal */} - {address && ( - setIsQrModalOpen(false)} - /> - )} + {address && setIsQrModalOpen(false)} />}
); } \ No newline at end of file diff --git a/frontend/app/dashboard/projects/page.tsx b/frontend/app/dashboard/projects/page.tsx index 7abcd63..8361028 100644 --- a/frontend/app/dashboard/projects/page.tsx +++ b/frontend/app/dashboard/projects/page.tsx @@ -2,7 +2,7 @@ import { Button } from '@/components/ui/button'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; -import { Plus, ExternalLink, Clock, Folder, Loader2 } from 'lucide-react'; +import { Plus, ExternalLink, Clock, Folder } from 'lucide-react'; import Link from 'next/link'; import { motion } from 'framer-motion'; import { ProjectCardSkeleton } from '@/components/ui/loading-skeletons'; @@ -29,13 +29,12 @@ export default function ProjectsPage() {

Projects

Manage your projects and milestones

- Loading projects...
-
+
{[1, 2, 3, 4].map((i) => ( ))} @@ -55,14 +54,10 @@ export default function ProjectsPage() { const getStatusColor = (status: string) => { switch (status) { - case 'active': - return 'bg-blue-100 text-blue-700 border-blue-200'; - case 'completed': - return 'bg-green-100 text-green-700 border-green-200'; - case 'cancelled': - return 'bg-red-100 text-red-700 border-red-200'; - default: - return 'bg-gray-100 text-gray-700 border-gray-200'; + case 'active': return 'bg-blue-100 text-blue-700 border-blue-200'; + case 'completed': return 'bg-green-100 text-green-700 border-green-200'; + case 'cancelled': return 'bg-red-100 text-red-700 border-red-200'; + default: return 'bg-gray-100 text-gray-700 border-gray-200'; } }; @@ -81,17 +76,11 @@ export default function ProjectsPage() {
-
+
{projects.map((project, index) => { - // Since contract uses 1 dummy milestone for status in our helper, we use that. - const completedMilestones = project.milestones.filter( - (m) => m.status === 'completed' - ).length; + const completedMilestones = project.milestones.filter((m) => m.status === 'completed').length; const totalMilestones = project.milestones.length; - const progressPercentage = - totalMilestones > 0 - ? (completedMilestones / totalMilestones) * 100 - : 0; + const progressPercentage = totalMilestones > 0 ? (completedMilestones / totalMilestones) * 100 : 0; return ( {project.title}

Client: {project.client.address.slice(0, 6)}...{project.client.address.slice(-4)}

- + {project.status}
@@ -120,9 +105,7 @@ export default function ProjectsPage() {
Total Value - - {project.totalAmount} {project.currency} - + {project.totalAmount} {project.currency}
@@ -131,10 +114,7 @@ export default function ProjectsPage() { {project.milestones[0]?.status.replace('_', ' ')}
-
+
@@ -164,15 +144,11 @@ export default function ProjectsPage() { icon={Folder} title="No projects found" description="Create your first project or wait to be hired." - action={{ - label: 'Create Project', - onClick: () => router.push('/dashboard/projects/new'), - }} + action={{ label: 'Create Project', onClick: () => router.push('/dashboard/projects/new') }} /> )}
); -} - +} \ No newline at end of file diff --git a/frontend/app/output.txt b/frontend/app/output.txt new file mode 100644 index 0000000..b122e97 --- /dev/null +++ b/frontend/app/output.txt @@ -0,0 +1,14 @@ +C:\Users\USER\Desktop\KING\Clones\agenticpay\frontend\app +├── accessibility +├── auth +├── dashboard +├── favicon.ico +├── globals.css +├── layout.tsx +├── manifest.ts +├── output.txt +├── page.tsx +└── service-worker.js + +directory: 4 file: 6 + diff --git a/frontend/components/layout/Header.tsx b/frontend/components/layout/Header.tsx index fc4d159..2f32043 100644 --- a/frontend/components/layout/Header.tsx +++ b/frontend/components/layout/Header.tsx @@ -36,6 +36,7 @@ import { getDashboardBreadcrumbs } from '@/lib/breadcrumbs'; import { ThemeSettingsModal } from '@/components/theme/ThemeSettingsModal'; import { TimezoneSettingsModal } from '@/components/settings/TimezoneSettingsModal'; import { getBrowserTimeZone, isValidTimeZone } from '@/lib/utils'; +import {Menu} from "lucide-react" /* ---------------- TYPES ---------------- */ type BreadcrumbItemType = { @@ -79,7 +80,11 @@ const NetworkIndicator = () => { }; /* ---------------- HEADER ---------------- */ -export function Header() { +export function Header({ + onMenuClick, + }: { + onMenuClick: () => void; + }) { const { name, email, address, timezone, logout, setTimezone } = useAuthStore(); const { isDark, mode, setIsDark } = useThemeStore(); @@ -145,9 +150,20 @@ export function Header() {
{/* LEFT */} -

- Dashboard -

+
+ + +

+ Dashboard +

+
{/* RIGHT */}
diff --git a/frontend/components/layout/Sidebar.tsx b/frontend/components/layout/Sidebar.tsx index 191ffe3..2e0a540 100644 --- a/frontend/components/layout/Sidebar.tsx +++ b/frontend/components/layout/Sidebar.tsx @@ -1,124 +1,54 @@ 'use client'; import Link from 'next/link'; -import { usePathname } from 'next/navigation'; -import { LayoutDashboard, Folder, FileText, Wallet, Menu, X } from 'lucide-react'; -import { useState } from 'react'; -import { Button } from '@/components/ui/button'; -import { cn } from '@/lib/utils'; -const navigation = [ - { name: 'Dashboard', href: '/dashboard', icon: LayoutDashboard }, - { name: 'Projects', href: '/dashboard/projects', icon: Folder }, - { name: 'Invoices', href: '/dashboard/invoices', icon: FileText }, - { name: 'Payments', href: '/dashboard/payments', icon: Wallet }, -]; - -export function Sidebar() { - const pathname = usePathname(); - const [isMobileOpen, setIsMobileOpen] = useState(false); +interface SidebarProps { + isOpen: boolean; + toggleSidebar: () => void; +} +export default function Sidebar({ isOpen, toggleSidebar }: SidebarProps) { return ( <> - {/* Mobile menu button */} -
- -
- {/* Sidebar */} + + {/* Mobile Overlay */} + {isOpen && ( +
+ )} ); } \ No newline at end of file diff --git a/frontend/components/layout/output.txt b/frontend/components/layout/output.txt new file mode 100644 index 0000000..b09ca9c --- /dev/null +++ b/frontend/components/layout/output.txt @@ -0,0 +1,7 @@ +C:\Users\USER\desktop\king\clones\agenticpay\frontend\components\layout +├── Header.tsx +├── PageBreadcrumb.tsx +└── Sidebar.tsx + +file: 3 + diff --git a/frontend/output.txt b/frontend/output.txt new file mode 100644 index 0000000..51246ed --- /dev/null +++ b/frontend/output.txt @@ -0,0 +1,23 @@ +C:\Users\USER\Desktop\KING\Clones\agenticpay\frontend +├── app +├── components +├── components.json +├── eslint.config.mjs +├── lib +├── next-env.d.ts +├── next.config.ts +├── node_modules +├── output.txt +├── package-lock.json +├── package.json +├── postcss.config.mjs +├── public +├── README.md +├── service-worker.ts +├── store +├── tsconfig.json +├── types +└── vitest.config.ts + +directory: 7 file: 12 +