Skip to content

Commit

Permalink
User Dashboard Basics implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
emekaorjiani committed Oct 20, 2024
1 parent 761b629 commit cd6efde
Show file tree
Hide file tree
Showing 18 changed files with 772 additions and 163 deletions.
77 changes: 77 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@radix-ui/react-dialog": "^1.1.2",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-tabs": "^1.1.1",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"lucide-react": "^0.453.0",
Expand Down
Binary file modified public/images/profile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/solana-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
68 changes: 0 additions & 68 deletions src/app/auth/register.tsx

This file was deleted.

26 changes: 15 additions & 11 deletions src/app/auth/register/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,27 @@ import { useRegister, RegisterData } from "@/queries/auth";
import { useRouter } from "next/navigation";

export default function Register() {
const [fullName, setFullName] = useState("");
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [registerError, setRegisterError] = useState<string | null>(null);

const router = useRouter();
const { mutate: register } = useRegister();
const { mutate: register, isLoading } = useRegister();

const handleRegister = (e: React.FormEvent) => {
e.preventDefault();
const registerData: RegisterData = { fullName, email, password };
const registerData: RegisterData = { name, email, password };
register(registerData, {
onSuccess: () => {
router.push('/auth/login');
},
onError: () => {
setRegisterError('Registration failed. Please try again.');
onError: (error: any) => {
if (error.response && error.response.data && error.response.data.message) {
setRegisterError(error.response.data.message);
} else {
setRegisterError('Registration failed. Please try again.');
}
}
});
};
Expand All @@ -47,13 +51,13 @@ export default function Register() {

<form onSubmit={handleRegister}>
<div className="mb-4">
<label className="block text-gray-700 mb-2">Full Name</label>
<label className="block text-gray-700 mb-2">Name</label>
<input
type="text"
className="w-full p-3 border border-gray-300 rounded-lg"
placeholder="Your Name"
value={fullName}
onChange={(e) => setFullName(e.target.value)}
value={name}
onChange={(e) => setName(e.target.value)}
required
/>
</div>
Expand Down Expand Up @@ -82,8 +86,8 @@ export default function Register() {
/>
</div>

<Button type="submit" className="w-full bg-green-600 text-white py-3 rounded-lg">
Create Account
<Button type="submit" className="w-full bg-green-600 text-white py-3 rounded-lg" disabled={isLoading}>
{isLoading ? 'Creating Account...' : 'Create Account'}
</Button>
</form>

Expand All @@ -108,4 +112,4 @@ export default function Register() {
</div>
</div>
);
}
}
59 changes: 45 additions & 14 deletions src/app/user/dashboard/page.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,68 @@
// src/app/user/dashboard/page.tsx
"use client";

import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { useVerifyToken, useLogout } from "@/queries/auth";
import { useLogout } from "@/queries/auth";
import { Button } from "@/components/ui/button";
import { QueryClient } from 'react-query';
import { getUser, getToken } from "@/utils/token";
import { ShoppingBag, Wallet, AlertCircle } from 'lucide-react';

export default function UserDashboard() {
const router = useRouter();
const { data: tokenStatus, isLoading, error } = useVerifyToken();
const [user, setUser] = useState(null);
const [queryClient] = useState(() => new QueryClient());
const logout = useLogout(queryClient);

useEffect(() => {
if (error || (tokenStatus && !tokenStatus.isValid)) {
const token = getToken();
const userData = getUser();
if (!token || !userData) {
router.push("/auth/login");
} else {
setUser(userData);
}
}, [error, tokenStatus, router]);

if (isLoading) {
return <div>Loading...</div>;
}
}, [router]);

const handleLogout = () => {
logout.mutate();
};

if (!user) {
return <div>Loading...</div>;
}

const widgets = [
{ title: 'Total Orders', value: '12', icon: ShoppingBag, color: 'bg-blue-500' },
{ title: 'Wallet Balance', value: '₦50,000', icon: Wallet, color: 'bg-green-500' },
{ title: 'Active Orders', value: '3', icon: AlertCircle, color: 'bg-yellow-500' },
];

return (
<div className="max-w-7xl mx-auto px-4 py-16">
<h1 className="text-4xl font-bold mb-8">Welcome to Your Dashboard</h1>
<p>Here you can view your recent orders, manage your profile, and much more!</p>
<Button onClick={handleLogout} className="mt-4 bg-red-600 text-white">Logout</Button>
{/* Add more dashboard-specific components here */}
<div>
<h1 className="text-2xl md:text-4xl font-bold mb-6">Welcome, {user.profile.first_name}!</h1>

<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8">
{widgets.map((widget, index) => (
<div key={index} className="bg-white rounded-lg shadow-md p-6 flex items-center">
<div className={`${widget.color} rounded-full p-3 mr-4`}>
<widget.icon className="h-6 w-6 text-white" />
</div>
<div>
<h3 className="text-lg font-semibold">{widget.title}</h3>
<p className="text-2xl font-bold">{widget.value}</p>
</div>
</div>
))}
</div>

<div className="bg-white rounded-lg shadow-md p-6 mb-8">
<h2 className="text-xl font-semibold mb-4">Recent Orders</h2>
{/* Add a table or list of recent orders here */}
</div>

<Button onClick={handleLogout} className="bg-red-600 text-white">Logout</Button>
</div>
);
}
}
50 changes: 50 additions & 0 deletions src/app/user/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// src/app/user/layout.tsx
"use client";

import { usePathname } from 'next/navigation';
import Link from 'next/link';
import { Settings, ShoppingBag, Ticket, Wallet } from 'lucide-react';

const menuItems = [
{ name: 'Dashboard', href: '/user/dashboard', icon: ShoppingBag },
{ name: 'Orders', href: '/user/orders', icon: ShoppingBag },
{ name: 'Wallet', href: '/user/wallet', icon: Wallet },
{ name: 'Tickets', href: '/user/tickets', icon: Ticket },
{ name: 'Settings', href: '/user/settings', icon: Settings },
];

export default function UserLayout({ children }: { children: React.ReactNode }) {
const pathname = usePathname();

return (
<div className="flex flex-col md:flex-row min-h-screen bg-gray-100">
{/* Sidebar - hidden on mobile, visible on md and larger screens */}
<aside className="hidden md:block w-64 bg-white shadow-lg">
<div className="flex flex-col h-full">
<div className="flex items-center justify-center h-16 bg-green-600 text-white">
<h2 className="text-2xl font-bold">FastBuka</h2>
</div>
<nav className="flex-1 px-4 py-4">
{menuItems.map((item) => (
<Link
key={item.name}
href={item.href}
className={`flex items-center py-2 px-4 rounded-lg mb-2 ${
pathname === item.href
? 'bg-green-100 text-green-700'
: 'text-gray-600 hover:bg-gray-100'
}`}
>
<item.icon className="mr-3 h-5 w-5" />
{item.name}
</Link>
))}
</nav>
</div>
</aside>

{/* Main content */}
<main className="flex-1 p-4 md:p-8">{children}</main>
</div>
);
}
Loading

0 comments on commit cd6efde

Please sign in to comment.