From 0032a4743c1a8692ae08d94e61960005cd93446e Mon Sep 17 00:00:00 2001 From: Om Lanke Date: Wed, 2 Jul 2025 22:10:56 +0530 Subject: [PATCH] student table optimization adn docker testing --- .dockerignore | 18 ++++++ Dockerfile | 29 +++++++++ apps/admin/Dockerfile | 29 +++++++++ apps/admin/app/(main)/page.tsx | 13 +--- apps/admin/app/(main)/students/columns.tsx | 27 ++++++-- apps/admin/app/(main)/students/data-table.tsx | 9 ++- apps/admin/app/(main)/students/error.tsx | 30 +++++++++ apps/admin/app/(main)/students/loading.tsx | 63 +++++++++++++++++++ apps/admin/app/(main)/students/page.tsx | 22 ++++++- apps/admin/next.config.mjs | 6 ++ apps/admin/package.json | 2 + apps/student/Dockerfile | 38 +++++++++++ apps/student/next.config.mjs | 6 ++ package.json | 1 + packages/ui/package.json | 2 +- packages/ui/src/components/skeleton.tsx | 12 ++++ pnpm-lock.yaml | 6 ++ turbo.json | 3 + 18 files changed, 297 insertions(+), 19 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 apps/admin/Dockerfile create mode 100644 apps/admin/app/(main)/students/error.tsx create mode 100644 apps/admin/app/(main)/students/loading.tsx create mode 100644 apps/student/Dockerfile create mode 100644 packages/ui/src/components/skeleton.tsx diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..12b7a58 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,18 @@ +Dockerfile +.dockerignore +node_modules +npm-debug.log +README.md +.next +.git +.pnp +.pnp.js +.turbo +.vercel +.next/ +out/ +build +dist +npm-debug.log* +.DS_Store +*.pem diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9767c4b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,29 @@ +FROM node:22-alpine AS base +ENV PNPM_HOME="/pnpm" +ENV PATH="$PNPM_HOME:$PATH" +RUN corepack enable && corepack prepare pnpm@latest --activate + +FROM base AS builder +RUN apk update && apk add --no-cache libc6-compat +WORKDIR /app +RUN pnpm add -g turbo@^2 +COPY . . +RUN turbo prune admin --docker + +FROM base AS installer +RUN apk update && apk add --no-cache libc6-compat +WORKDIR /app +COPY --from=builder /app/out/json/ . +RUN pnpm fetch --frozen-lockfile +RUN pnpm install --offline --frozen-lockfile --prod=false +COPY --from=builder /app/out/full/ . +RUN pnpm turbo run build + +FROM base AS runner +WORKDIR /app +RUN addgroup --system --gid 1001 nodejs && adduser --system --uid 1001 nextjs +USER nextjs +COPY --from=installer --chown=nextjs:nodejs /app/apps/web/.next/standalone ./ +COPY --from=installer --chown=nextjs:nodejs /app/apps/web/.next/static ./apps/web/.next/static +COPY --from=installer --chown=nextjs:nodejs /app/apps/web/public ./apps/web/public +CMD node apps/web/server.js diff --git a/apps/admin/Dockerfile b/apps/admin/Dockerfile new file mode 100644 index 0000000..9767c4b --- /dev/null +++ b/apps/admin/Dockerfile @@ -0,0 +1,29 @@ +FROM node:22-alpine AS base +ENV PNPM_HOME="/pnpm" +ENV PATH="$PNPM_HOME:$PATH" +RUN corepack enable && corepack prepare pnpm@latest --activate + +FROM base AS builder +RUN apk update && apk add --no-cache libc6-compat +WORKDIR /app +RUN pnpm add -g turbo@^2 +COPY . . +RUN turbo prune admin --docker + +FROM base AS installer +RUN apk update && apk add --no-cache libc6-compat +WORKDIR /app +COPY --from=builder /app/out/json/ . +RUN pnpm fetch --frozen-lockfile +RUN pnpm install --offline --frozen-lockfile --prod=false +COPY --from=builder /app/out/full/ . +RUN pnpm turbo run build + +FROM base AS runner +WORKDIR /app +RUN addgroup --system --gid 1001 nodejs && adduser --system --uid 1001 nextjs +USER nextjs +COPY --from=installer --chown=nextjs:nodejs /app/apps/web/.next/standalone ./ +COPY --from=installer --chown=nextjs:nodejs /app/apps/web/.next/static ./apps/web/.next/static +COPY --from=installer --chown=nextjs:nodejs /app/apps/web/public ./apps/web/public +CMD node apps/web/server.js diff --git a/apps/admin/app/(main)/page.tsx b/apps/admin/app/(main)/page.tsx index adda14f..4103738 100644 --- a/apps/admin/app/(main)/page.tsx +++ b/apps/admin/app/(main)/page.tsx @@ -1,19 +1,13 @@ -import Login from '@/components/login'; import Studs from '@/components/studs'; -import { db, admins } from '@workspace/db'; -import { auth, signIn, signOut } from '@/auth'; +import { db, students } from '@workspace/db'; +import { auth, signOut } from '@/auth'; async function getStudents() { 'use server'; - const s = await db.select().from(admins); + const s = await db.select().from(students); console.log(s); } -async function logIn() { - 'use server'; - await signIn('google'); -} - async function logOut() { 'use server'; await signOut(); @@ -25,7 +19,6 @@ export default async function Page() {

Hello admin {session?.user?.name}

- {!session?.user && }
diff --git a/apps/admin/app/(main)/students/columns.tsx b/apps/admin/app/(main)/students/columns.tsx index 239ac0e..4d6fda6 100644 --- a/apps/admin/app/(main)/students/columns.tsx +++ b/apps/admin/app/(main)/students/columns.tsx @@ -6,20 +6,39 @@ const studentSelectSchema = createSelectSchema(students); export type Student = z.infer; export const columns: ColumnDef[] = [ - { - accessorKey: 'id', - header: 'ID', - }, { accessorKey: 'firstName', header: 'First Name', + filterFn: 'includesString', }, { accessorKey: 'lastName', header: 'Last Name', + filterFn: 'includesString', + }, + { + accessorKey: 'rollNumber', + header: 'Roll Number', + filterFn: 'includesString', }, { accessorKey: 'email', header: 'Email', + filterFn: 'includesString', + }, + { + accessorKey: 'yearOfGraduation', + header: 'Year of Graduation', + filterFn: 'includesString', + }, + { + accessorKey: 'degree', + header: 'Degree', + filterFn: 'includesString', + }, + { + accessorKey: 'branch', + header: 'Branch', + filterFn: 'includesString', }, ]; diff --git a/apps/admin/app/(main)/students/data-table.tsx b/apps/admin/app/(main)/students/data-table.tsx index 3a8dd74..fc097df 100644 --- a/apps/admin/app/(main)/students/data-table.tsx +++ b/apps/admin/app/(main)/students/data-table.tsx @@ -1,6 +1,12 @@ 'use client'; -import { ColumnDef, flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table'; +import { + ColumnDef, + flexRender, + getCoreRowModel, + getPaginationRowModel, + useReactTable, +} from '@tanstack/react-table'; import { Table, @@ -21,6 +27,7 @@ export function DataTable({ columns, data }: DataTableProps void; +}) { + useEffect(() => { + console.error('Students page error:', error); + }, [error]); + + return ( +
+
+

Something went wrong!

+

+ Failed to load students data. Please try again. +

+ +
+
+ ); +} diff --git a/apps/admin/app/(main)/students/loading.tsx b/apps/admin/app/(main)/students/loading.tsx new file mode 100644 index 0000000..4575c60 --- /dev/null +++ b/apps/admin/app/(main)/students/loading.tsx @@ -0,0 +1,63 @@ +import { Skeleton } from '@workspace/ui/components/skeleton'; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from '@workspace/ui/components/table'; + +export default function Loading() { + return ( +
+
+ {/* Header skeleton */} +
+

Students

+ +
+ + {/* Table skeleton */} +
+ + + + + + + + + + + + + + + + + + + {Array.from({ length: 8 }).map((_, index) => ( + + + + + + + + + + + + + + + ))} + +
+
+
+
+ ); +} \ No newline at end of file diff --git a/apps/admin/app/(main)/students/page.tsx b/apps/admin/app/(main)/students/page.tsx index ec18ffb..543735b 100644 --- a/apps/admin/app/(main)/students/page.tsx +++ b/apps/admin/app/(main)/students/page.tsx @@ -3,16 +3,32 @@ import { DataTable } from './data-table'; import { db, students } from '@workspace/db'; async function getData(): Promise { - const data = db.select().from(students); + const data = await db.select().from(students); return data; } -export default async function DemoPage() { +async function StudentsTable() { const data = await getData(); return (
- +
+
+

Students

+
+ {data.length} {data.length === 1 ? 'student' : 'students'} total +
+
+ +
); } + +export default function StudentsPage() { + return ( + + ); +} + +export const dynamic = 'force-dynamic'; \ No newline at end of file diff --git a/apps/admin/next.config.mjs b/apps/admin/next.config.mjs index 3538f42..0f9b693 100644 --- a/apps/admin/next.config.mjs +++ b/apps/admin/next.config.mjs @@ -1,6 +1,12 @@ /** @type {import('next').NextConfig} */ +import path from 'path'; + +const __dirname = path.resolve(); + const nextConfig = { transpilePackages: ['@workspace/ui', '@workspace/db'], + output: 'standalone', + outputFileTracingRoot: path.join(__dirname, '../../'), }; export default nextConfig; diff --git a/apps/admin/package.json b/apps/admin/package.json index 039df49..a8693da 100644 --- a/apps/admin/package.json +++ b/apps/admin/package.json @@ -12,6 +12,7 @@ "typecheck": "tsc --noEmit" }, "dependencies": { + "@tailwindcss/postcss": "^4.0.8", "@tanstack/react-table": "^8.21.3", "@workspace/db": "workspace:*", "@workspace/ui": "workspace:*", @@ -22,6 +23,7 @@ "next-themes": "^0.4.6", "react": "^19.1.0", "react-dom": "^19.1.0", + "tailwindcss": "^4.0.8", "zod": "^3.25.67" }, "devDependencies": { diff --git a/apps/student/Dockerfile b/apps/student/Dockerfile new file mode 100644 index 0000000..c5d53bd --- /dev/null +++ b/apps/student/Dockerfile @@ -0,0 +1,38 @@ +FROM node:22-alpine AS base + +FROM base AS builder +RUN apk update +RUN apk add --no-cache libc6-compat +WORKDIR /app + +RUN corepack enable pnpm && pnpm add -g turbo@^2 +COPY . . + +RUN turbo prune student --docker + +FROM base AS installer +RUN apk update +RUN apk add --no-cache libc6-compat +WORKDIR /app + +COPY --from=builder /app/out/json/ . +RUN yarn install --frozen-lockfile + +COPY --from=builder /app/out/full/ . +RUN pnpm turbo run build + +FROM base AS runner +WORKDIR /app + +# Don't run production as root +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs +USER nextjs + +# Automatically leverage output traces to reduce image size +# https://nextjs.org/docs/advanced-features/output-file-tracing +COPY --from=installer --chown=nextjs:nodejs /app/apps/web/.next/standalone ./ +COPY --from=installer --chown=nextjs:nodejs /app/apps/web/.next/static ./apps/web/.next/static +COPY --from=installer --chown=nextjs:nodejs /app/apps/web/public ./apps/web/public + +CMD node apps/web/server.js \ No newline at end of file diff --git a/apps/student/next.config.mjs b/apps/student/next.config.mjs index 3538f42..0f9b693 100644 --- a/apps/student/next.config.mjs +++ b/apps/student/next.config.mjs @@ -1,6 +1,12 @@ /** @type {import('next').NextConfig} */ +import path from 'path'; + +const __dirname = path.resolve(); + const nextConfig = { transpilePackages: ['@workspace/ui', '@workspace/db'], + output: 'standalone', + outputFileTracingRoot: path.join(__dirname, '../../'), }; export default nextConfig; diff --git a/package.json b/package.json index 36d68b1..9bfafed 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "build": "turbo build", "dev": "turbo dev", "lint": "turbo lint", + "start": "turbo start", "format": "prettier --write \"**/*.{ts,tsx,md}\"", "db:check": "pnpm --filter @workspace/db check", "db:generate": "pnpm --filter @workspace/db generate", diff --git a/packages/ui/package.json b/packages/ui/package.json index 51476e4..a9d9bb1 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -43,4 +43,4 @@ "./components/*": "./src/components/*.tsx", "./hooks/*": "./src/hooks/*.ts" } -} +} \ No newline at end of file diff --git a/packages/ui/src/components/skeleton.tsx b/packages/ui/src/components/skeleton.tsx new file mode 100644 index 0000000..3b1cabd --- /dev/null +++ b/packages/ui/src/components/skeleton.tsx @@ -0,0 +1,12 @@ +import { cn } from '@workspace/ui/lib/utils'; + +function Skeleton({ className, ...props }: React.HTMLAttributes) { + return ( +
+ ); +} + +export { Skeleton }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 51bf53a..72141d4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,6 +26,9 @@ importers: apps/admin: dependencies: + '@tailwindcss/postcss': + specifier: ^4.0.8 + version: 4.1.11 '@tanstack/react-table': specifier: ^8.21.3 version: 8.21.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -56,6 +59,9 @@ importers: react-dom: specifier: ^19.1.0 version: 19.1.0(react@19.1.0) + tailwindcss: + specifier: ^4.0.8 + version: 4.1.11 zod: specifier: ^3.25.67 version: 3.25.67 diff --git a/turbo.json b/turbo.json index d6a7fe0..41e8594 100644 --- a/turbo.json +++ b/turbo.json @@ -16,6 +16,9 @@ "dev": { "cache": false, "persistent": true + }, + "start": { + "persistent": true } } }