diff --git a/Dockerfile b/Dockerfile index 5f41ba9..6743868 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,7 +29,7 @@ RUN bun x prisma generate # Generate API types RUN bun run gen:api -# Build the application frontend +# Build the application frontend using our custom build script RUN bun run build # Stage 2: Runtime diff --git a/package.json b/package.json index b835530..4ed17fa 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "test": "bun test __tests__/api", "test:ui": "bun test --ui __tests__/api", "test:e2e": "bun run build && playwright test", - "build": "bun build ./src/index.html --outdir=dist --sourcemap --target=browser --minify --define:process.env.NODE_ENV='\"production\"' --env='VITE_*' && cp -r public/* dist/ 2>/dev/null || true", + "build": "bun run scripts/build.ts", "start": "NODE_ENV=production bun src/index.ts", "seed": "bun prisma/seed.ts" }, diff --git a/scripts/build.ts b/scripts/build.ts new file mode 100644 index 0000000..e80eade --- /dev/null +++ b/scripts/build.ts @@ -0,0 +1,58 @@ +#!/usr/bin/env bun + +/** + * Build script for production + * 1. Build CSS with PostCSS/Tailwind + * 2. Bundle JS with Bun (without CSS) + * 3. Replace CSS reference in HTML + */ + +import { $ } from "bun"; +import fs from "node:fs"; +import postcss from "postcss"; +import tailwindcss from "@tailwindcss/postcss"; +import autoprefixer from "autoprefixer"; + +console.log("🔨 Starting production build..."); + +// Ensure dist directory exists +if (!fs.existsSync("./dist")) { + fs.mkdirSync("./dist", { recursive: true }); +} + +// Step 1: Build CSS with PostCSS +console.log("🎨 Building CSS..."); +const cssInput = fs.readFileSync("./src/index.css", "utf-8"); +const cssResult = await postcss([tailwindcss(), autoprefixer()]).process( + cssInput, + { + from: "./src/index.css", + to: "./dist/index.css", + }, +); + +fs.writeFileSync("./dist/index.css", cssResult.css); +console.log("✅ CSS built successfully!"); + +// Step 2: Build JS with Bun (build HTML too, we'll fix CSS link later) +console.log("📦 Bundling JavaScript..."); +await $`bun build ./src/index.html --outdir=dist --sourcemap --target=browser --minify --define:process.env.NODE_ENV='"production"' --env='VITE_*'`; + +// Step 3: Copy public assets +console.log("📁 Copying public assets..."); +if (fs.existsSync("./public")) { + await $`cp -r public/* dist/ 2>/dev/null || true`; +} + +// Step 4: Ensure HTML references the correct CSS +// Bun build might have renamed the CSS, we want to use our own index.css +console.log("🔧 Fixing HTML CSS reference..."); +const htmlPath = "./dist/index.html"; +if (fs.existsSync(htmlPath)) { + let html = fs.readFileSync(htmlPath, "utf-8"); + // Replace any bundled CSS reference with our index.css + html = html.replace(/href="[^"]*\.css"/g, 'href="/index.css"'); + fs.writeFileSync(htmlPath, html); +} + +console.log("✅ Build completed successfully!"); diff --git a/src/components/bumdes-page.tsx b/src/components/bumdes-page.tsx index 5a34605..605a8e8 100644 --- a/src/components/bumdes-page.tsx +++ b/src/components/bumdes-page.tsx @@ -149,16 +149,40 @@ const BumdesPage = () => { return (
{ {product.umkmOwner}
+
{product.sales}
{
+
{kpi.delta}
)} @@ -176,7 +200,13 @@ const KeuanganAnggaran = () => { {/* Row 2: Line Chart Section */}{stat.value}
{stat.subtitle}
{item.nama}
{item.tanggal}
{scholarshipData.penerima}
Penerima Beasiswa
{scholarshipData.dana}
Dana Tersalurkan
@@ -413,8 +411,9 @@ const SosialPage = () => { {/* Footer text */}Tahun Ajaran {scholarshipData.tahunAjaran}
@@ -422,12 +421,14 @@ const SosialPage = () => { {/* Kalender Event Budaya */}{event.nama}
{event.tanggal}
Location: {event.lokasi}
diff --git a/src/index.css b/src/index.css index f1d8c73..3dc36b0 100644 --- a/src/index.css +++ b/src/index.css @@ -1 +1,100 @@ @import "tailwindcss"; + +/* Custom CSS variables for Tailwind */ +:root { + /* Darmasaba Navy Colors */ + --darmasaba-navy-50: #E1E4F2; + --darmasaba-navy-100: #B9C2DD; + --darmasaba-navy-200: #91A0C9; + --darmasaba-navy-300: #697EBA; + --darmasaba-navy-400: #4C6CAE; + --darmasaba-navy-500: #3B5B97; + --darmasaba-navy-600: #2C497F; + --darmasaba-navy-700: #1E3766; + --darmasaba-navy-800: #12264D; + --darmasaba-navy-900: #071833; + --darmasaba-navy: #1E3A5F; + + /* Darmasaba Blue Colors */ + --darmasaba-blue-50: #E3F0FF; + --darmasaba-blue-100: #B6D9FF; + --darmasaba-blue-200: #89C2FF; + --darmasaba-blue-300: #5CA9FF; + --darmasaba-blue-400: #3B8FFF; + --darmasaba-blue-500: #237AE0; + --darmasaba-blue-600: #1C6BBF; + --darmasaba-blue-700: #155BA0; + --darmasaba-blue-800: #0E4980; + --darmasaba-blue-900: #073260; + --darmasaba-blue: #3B82F6; + + /* Darmasaba Success Colors */ + --darmasaba-success-50: #E3F9E7; + --darmasaba-success-100: #BFEEC7; + --darmasaba-success-200: #9BD8A7; + --darmasaba-success-300: #77C387; + --darmasaba-success-400: #5DB572; + --darmasaba-success-500: #499A5D; + --darmasaba-success-600: #3C7F4A; + --darmasaba-success-700: #2F6438; + --darmasaba-success-800: #234926; + --darmasaba-success-900: #17301B; + --darmasaba-success: #22C55E; + + /* Darmasaba Warning Colors */ + --darmasaba-warning-50: #FFF8E1; + --darmasaba-warning-100: #FEE7B3; + --darmasaba-warning-200: #FDD785; + --darmasaba-warning-300: #FDC757; + --darmasaba-warning-400: #FBBF3B; + --darmasaba-warning-500: #E1AC23; + --darmasaba-warning-600: #C2981D; + --darmasaba-warning-700: #A38418; + --darmasaba-warning-800: #856F12; + --darmasaba-warning-900: #675A0D; + --darmasaba-warning: #FACC15; + + /* Darmasaba Danger Colors */ + --darmasaba-danger-50: #FFE3E3; + --darmasaba-danger-100: #FFBABA; + --darmasaba-danger-200: #FF9191; + --darmasaba-danger-300: #FF6868; + --darmasaba-danger-400: #FA4B4B; + --darmasaba-danger-500: #E03333; + --darmasaba-danger-600: #C22A2A; + --darmasaba-danger-700: #A32020; + --darmasaba-danger-800: #851616; + --darmasaba-danger-900: #670C0C; + --darmasaba-danger: #EF4444; + + /* Darmasaba Background */ + --darmasaba-background: #F5F8FB; + + /* Standard colors for dark mode */ + --slate-900: #0F172A; + --slate-800: #1E293B; + --slate-700: #334155; + --slate-600: #475569; + --gray-50: #F9FAFB; + --gray-100: #F3F4F6; + --gray-200: #E5E7EB; + --gray-600: #4B5563; + --gray-700: #1F2937; + --gray-400: #9CA3AF; + --gray-500: #6B7280; + --gray-800: #1F2937; + --blue-50: #EFF6FF; + --blue-100: #DBEAFE; + --blue-900: #1E3A5F; + --red-500: #EF4444; + --green-500: #22C55E; +} + +/* Dark mode support */ +[data-mantine-color-scheme="dark"] { + color-scheme: dark; +} + +[data-mantine-color-scheme="light"] { + color-scheme: light; +} diff --git a/tailwind.config.js b/tailwind.config.js index 3623a49..4a9d1b2 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,11 +1,15 @@ /** @type {import('tailwindcss').Config} */ module.exports = { - content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"], + content: [ + "./src/index.html", + "./public/**/*.html", + "./src/**/*.{js,ts,jsx,tsx}", + ], theme: { extend: { colors: { "darmasaba-navy": { - DEFAULT: "#1E3A5F", // Primary navy color + DEFAULT: "#1E3A5F", 50: "#E1E4F2", 100: "#B9C2DD", 200: "#91A0C9", @@ -18,7 +22,7 @@ module.exports = { 900: "#071833", }, "darmasaba-blue": { - DEFAULT: "#3B82F6", // Primary blue color + DEFAULT: "#3B82F6", 50: "#E3F0FF", 100: "#B6D9FF", 200: "#89C2FF",