mirror of
https://github.com/SrIzan10/echospace.git
synced 2026-06-06 00:56:54 +00:00
feat: add dashboard with dummy data
This commit is contained in:
8
.prettierrc
Normal file
8
.prettierrc
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"useTabs": false,
|
||||
"printWidth": 800,
|
||||
"tabWidth": 2,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "es5",
|
||||
"semi": true
|
||||
}
|
||||
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"editor.tabSize": 2,
|
||||
"editor.detectIndentation": false,
|
||||
"editor.insertSpaces": true,
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
services:
|
||||
psql:
|
||||
image: postgres
|
||||
user: 1000:1000
|
||||
environment:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: S+xyPXPDcYNQtTy3hUNoC9eBwmsoGA
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
"start": "next start",
|
||||
"lint": "next lint",
|
||||
"db:generate": "prisma generate",
|
||||
"db:migrate": "prisma migrate dev --name"
|
||||
"db:migrate": "prisma migrate dev --name",
|
||||
"ui:add": "shadcn add"
|
||||
},
|
||||
"dependencies": {
|
||||
"@lucia-auth/adapter-prisma": "^4.0.1",
|
||||
@@ -30,9 +31,10 @@
|
||||
"sonner": "^1.4.41",
|
||||
"tailwind-merge": "^2.2.2",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"zod": "^3.23.8"
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@faker-js/faker": "^9.3.0",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^18",
|
||||
"@types/react-dom": "^18",
|
||||
@@ -40,6 +42,7 @@
|
||||
"eslint-config-next": "14.2.0",
|
||||
"postcss": "^8",
|
||||
"prisma": "^6.0.1",
|
||||
"shadcn": "^2.1.7",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"typescript": "^5"
|
||||
},
|
||||
|
||||
0
src/app/(protected)/create/page.tsx
Normal file
0
src/app/(protected)/create/page.tsx
Normal file
11
src/app/(protected)/dashboard/loading.tsx
Normal file
11
src/app/(protected)/dashboard/loading.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import { ProjectCardSkeleton } from '@/components/app/ProjectCard/ProjectCard';
|
||||
|
||||
export default function Loading() {
|
||||
return (
|
||||
<div className="grid grid-cols-1 gap-8 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 p-4">
|
||||
{Array.from({ length: 8 }).map((_, i) => (
|
||||
<ProjectCardSkeleton key={i} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
21
src/app/(protected)/dashboard/page.tsx
Normal file
21
src/app/(protected)/dashboard/page.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import ProjectCard from '@/components/app/ProjectCard/ProjectCard';
|
||||
import { faker } from '@faker-js/faker';
|
||||
|
||||
export const dummyData = Array.from({ length: 10 }, (_, id) => ({
|
||||
id: id + 1,
|
||||
name: faker.word.noun(),
|
||||
description: faker.lorem.sentence(),
|
||||
github: id !== 5 ? faker.internet.url() : undefined,
|
||||
}));
|
||||
export default function Page() {
|
||||
return (
|
||||
<>
|
||||
<h1>Dashboard</h1>
|
||||
<div className="grid grid-cols-1 gap-8 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 p-4">
|
||||
{dummyData.map((d) => (
|
||||
<ProjectCard key={d.id} {...d} />
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
0
src/app/(protected)/project/[id].tsx
Normal file
0
src/app/(protected)/project/[id].tsx
Normal file
@@ -1,12 +0,0 @@
|
||||
import { validateRequest } from "@/lib/auth";
|
||||
|
||||
export default async function Page() {
|
||||
const { user } = await validateRequest()
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold text-center">Welcome {user?.username}!</h1>
|
||||
<p>You are actually on a protected route!</p>
|
||||
<p>Your ID is: {user!.id}</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -18,8 +18,7 @@ import { ThemeSwitcher } from "../ThemeSwitcher/ThemeSwitcher"
|
||||
|
||||
export const links = [
|
||||
{ href: '/', name: 'Home' },
|
||||
{ href: 'https://github.com/SrIzan10/stack', name: 'Github' },
|
||||
{ href: '/protected', name: 'Protected route' }
|
||||
{ href: '/dashboard', name: 'Dashboard' }
|
||||
]
|
||||
|
||||
function NavbarLinks() {
|
||||
|
||||
48
src/components/app/ProjectCard/ProjectCard.tsx
Normal file
48
src/components/app/ProjectCard/ProjectCard.tsx
Normal file
@@ -0,0 +1,48 @@
|
||||
import { dummyData } from '@/app/(protected)/dashboard/page';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Skeleton } from '@/components/ui/skeleton';
|
||||
import { Eye, Github } from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function ProjectCard(props: (typeof dummyData)[0]) {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>{props.name}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>{props.description}</CardContent>
|
||||
<CardFooter className="flex justify-end gap-5">
|
||||
<Link href={`/project/${props.id}`}>
|
||||
<Button size={'icon'}>
|
||||
<Eye />
|
||||
</Button>
|
||||
</Link>
|
||||
{props.github && (
|
||||
<Link href={props.github}>
|
||||
<Button size={'icon'}>
|
||||
<Github />
|
||||
</Button>
|
||||
</Link>
|
||||
)}
|
||||
</CardFooter>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
export function ProjectCardSkeleton() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<Skeleton className="h-6 w-[200px]" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Skeleton className="h-4 w-full" />
|
||||
</CardContent>
|
||||
<CardFooter className="flex justify-end gap-5">
|
||||
<Skeleton className="h-9 w-9 rounded-md" />
|
||||
<Skeleton className="h-9 w-9 rounded-md" />
|
||||
</CardFooter>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
79
src/components/ui/card.tsx
Normal file
79
src/components/ui/card.tsx
Normal file
@@ -0,0 +1,79 @@
|
||||
import * as React from "react"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const Card = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"rounded-lg border bg-card text-card-foreground shadow-sm",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
Card.displayName = "Card"
|
||||
|
||||
const CardHeader = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn("flex flex-col space-y-1.5 p-6", className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
CardHeader.displayName = "CardHeader"
|
||||
|
||||
const CardTitle = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"text-2xl font-semibold leading-none tracking-tight",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
CardTitle.displayName = "CardTitle"
|
||||
|
||||
const CardDescription = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn("text-sm text-muted-foreground", className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
CardDescription.displayName = "CardDescription"
|
||||
|
||||
const CardContent = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
|
||||
))
|
||||
CardContent.displayName = "CardContent"
|
||||
|
||||
const CardFooter = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn("flex items-center p-6 pt-0", className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
CardFooter.displayName = "CardFooter"
|
||||
|
||||
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
|
||||
15
src/components/ui/skeleton.tsx
Normal file
15
src/components/ui/skeleton.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
function Skeleton({
|
||||
className,
|
||||
...props
|
||||
}: React.HTMLAttributes<HTMLDivElement>) {
|
||||
return (
|
||||
<div
|
||||
className={cn("animate-pulse rounded-md bg-muted", className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export { Skeleton }
|
||||
Reference in New Issue
Block a user