From 9a93ead8b50dfa8dc31b238169f5c77e5ac968d6 Mon Sep 17 00:00:00 2001 From: ibuzzardo Date: Mon, 2 Mar 2026 10:06:34 +1100 Subject: [PATCH 1/2] feat: [Dark Factory] Scaffold for a self-hosted Next.js 15 VPS Command Center dashboard with dark-themed Tailwind UI and system metrics API. Generated by Dark Factory v4 pipeline job cmm8cqfch0002ykwinlr4p6r3 --- .env.example | 2 + .gitignore | 46 +++++++++++++++ next.config.js | 12 ++++ package.json | 27 +++++++++ postcss.config.js | 6 ++ src/app/api/system/route.ts | 37 ++++++++++++ src/app/globals.css | 44 +++++++++++++++ src/app/layout.tsx | 24 ++++++++ src/app/page.tsx | 109 ++++++++++++++++++++++++++++++++++++ src/lib/types.ts | 10 ++++ tailwind.config.ts | 30 ++++++++++ tsconfig.json | 31 ++++++++++ 12 files changed, 378 insertions(+) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 next.config.js create mode 100644 package.json create mode 100644 postcss.config.js create mode 100644 src/app/api/system/route.ts create mode 100644 src/app/globals.css create mode 100644 src/app/layout.tsx create mode 100644 src/app/page.tsx create mode 100644 src/lib/types.ts create mode 100644 tailwind.config.ts create mode 100644 tsconfig.json diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..7ec6f0a --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +VPS_API_KEY=your-api-key-here +PORT=4002 \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a8dfcf7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,46 @@ +# Dependencies +node_modules/ + +# Next.js +.next/ +out/ + +# Production +build/ +dist/ + +# Environment variables +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# Logs +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Coverage directory used by tools like istanbul +coverage/ +*.lcov + +# nyc test coverage +.nyc_output + +# OS +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db \ No newline at end of file diff --git a/next.config.js b/next.config.js new file mode 100644 index 0000000..b6ffb64 --- /dev/null +++ b/next.config.js @@ -0,0 +1,12 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + output: 'standalone', + experimental: { + typedRoutes: true + }, + env: { + PORT: process.env.PORT || '4002' + } +}; + +module.exports = nextConfig; \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..47d4a61 --- /dev/null +++ b/package.json @@ -0,0 +1,27 @@ +{ + "name": "vps-command-center", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev -p 4002", + "build": "next build", + "start": "next start -p 4002", + "lint": "next lint" + }, + "dependencies": { + "next": "^15.0.0", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "systeminformation": "^5.21.20", + "zod": "^3.22.4" + }, + "devDependencies": { + "@types/node": "^20.0.0", + "@types/react": "^18.0.0", + "@types/react-dom": "^18.0.0", + "autoprefixer": "^10.4.16", + "postcss": "^8.4.31", + "tailwindcss": "^3.3.5", + "typescript": "^5.0.0" + } +} \ No newline at end of file diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..7fbaf2a --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {} + } +}; \ No newline at end of file diff --git a/src/app/api/system/route.ts b/src/app/api/system/route.ts new file mode 100644 index 0000000..a2a5279 --- /dev/null +++ b/src/app/api/system/route.ts @@ -0,0 +1,37 @@ +import { NextResponse } from 'next/server'; +import * as si from 'systeminformation'; +import type { SystemMetrics } from '@/lib/types'; + +export async function GET(): Promise> { + try { + const [cpu, mem, disk, network] = await Promise.all([ + si.currentLoad(), + si.mem(), + si.fsSize(), + si.networkStats() + ]); + + const uptime = si.time().uptime; + const primaryDisk = disk[0] || { used: 0, size: 1 }; + const primaryNetwork = network[0] || { rx_bytes: 0, tx_bytes: 0 }; + + const metrics: SystemMetrics = { + cpu: Math.round(cpu.currentLoad || 0), + memoryUsed: mem.used, + memoryTotal: mem.total, + diskUsed: primaryDisk.used, + diskTotal: primaryDisk.size, + networkRx: primaryNetwork.rx_bytes, + networkTx: primaryNetwork.tx_bytes, + uptime: uptime + }; + + return NextResponse.json(metrics); + } catch (error) { + console.error('System metrics error:', error); + return NextResponse.json( + { error: 'Failed to fetch system metrics' }, + { status: 500 } + ); + } +} \ No newline at end of file diff --git a/src/app/globals.css b/src/app/globals.css new file mode 100644 index 0000000..45e4ff3 --- /dev/null +++ b/src/app/globals.css @@ -0,0 +1,44 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +:root { + --background: #0B1120; + --foreground: #F9FAFB; + --card: #111827; + --card-foreground: #F9FAFB; + --border: #374151; + --muted: #9CA3AF; + --muted-foreground: #9CA3AF; + --primary: #3B82F6; + --primary-foreground: #F9FAFB; + --accent: #3B82F6; + --accent-foreground: #F9FAFB; + --destructive: #EF4444; + --destructive-foreground: #F9FAFB; +} + +.dark { + --background: #0B1120; + --foreground: #F9FAFB; + --card: #111827; + --card-foreground: #F9FAFB; + --border: #374151; + --muted: #9CA3AF; + --muted-foreground: #9CA3AF; + --primary: #3B82F6; + --primary-foreground: #F9FAFB; + --accent: #3B82F6; + --accent-foreground: #F9FAFB; + --destructive: #EF4444; + --destructive-foreground: #F9FAFB; +} + +* { + border-color: hsl(var(--border)); +} + +body { + color: hsl(var(--foreground)); + background: hsl(var(--background)); +} \ No newline at end of file diff --git a/src/app/layout.tsx b/src/app/layout.tsx new file mode 100644 index 0000000..e135e80 --- /dev/null +++ b/src/app/layout.tsx @@ -0,0 +1,24 @@ +import type { Metadata } from 'next'; +import { Inter } from 'next/font/google'; +import './globals.css'; + +const inter = Inter({ subsets: ['latin'] }); + +export const metadata: Metadata = { + title: 'VPS Command Center', + description: 'Self-hosted VPS monitoring dashboard' +}; + +export default function RootLayout({ + children +}: { + children: React.ReactNode; +}): JSX.Element { + return ( + + +
{children}
+ + + ); +} \ No newline at end of file diff --git a/src/app/page.tsx b/src/app/page.tsx new file mode 100644 index 0000000..3b971a7 --- /dev/null +++ b/src/app/page.tsx @@ -0,0 +1,109 @@ +'use client'; + +import { useEffect, useState } from 'react'; +import type { SystemMetrics } from '@/lib/types'; + +function formatBytes(bytes: number): string { + const gb = bytes / (1024 * 1024 * 1024); + return `${gb.toFixed(1)} GB`; +} + +function formatUptime(seconds: number): string { + const days = Math.floor(seconds / 86400); + const hours = Math.floor((seconds % 86400) / 3600); + const minutes = Math.floor((seconds % 3600) / 60); + return `${days}d ${hours}h ${minutes}m`; +} + +export default function Dashboard(): JSX.Element { + const [metrics, setMetrics] = useState(null); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const fetchMetrics = async (): Promise => { + try { + const response = await fetch('/api/system'); + if (response.ok) { + const data = await response.json(); + setMetrics(data); + } + } catch (error) { + console.error('Failed to fetch metrics:', error); + } finally { + setLoading(false); + } + }; + + fetchMetrics(); + const interval = setInterval(fetchMetrics, 3000); + + return () => clearInterval(interval); + }, []); + + if (loading) { + return ( +
+

VPS Command Center

+
+ {Array.from({ length: 6 }).map((_, i) => ( +
+
+
+
+
+
+ ))} +
+
+ ); + } + + return ( +
+

VPS Command Center

+
+
+

CPU Usage

+

+ {metrics?.cpu ?? 'TODO'}% +

+
+ +
+

Memory

+

+ {metrics ? `${formatBytes(metrics.memoryUsed)} / ${formatBytes(metrics.memoryTotal)}` : 'TODO'} +

+
+ +
+

Disk Usage

+

+ {metrics ? `${formatBytes(metrics.diskUsed)} / ${formatBytes(metrics.diskTotal)}` : 'TODO'} +

+
+ +
+

Network RX

+

+ {metrics ? formatBytes(metrics.networkRx) : 'TODO'} +

+
+ +
+

Network TX

+

+ {metrics ? formatBytes(metrics.networkTx) : 'TODO'} +

+
+ +
+

Uptime

+

+ {metrics ? formatUptime(metrics.uptime) : 'TODO'} +

+
+
+
+ ); +} \ No newline at end of file diff --git a/src/lib/types.ts b/src/lib/types.ts new file mode 100644 index 0000000..700af49 --- /dev/null +++ b/src/lib/types.ts @@ -0,0 +1,10 @@ +export interface SystemMetrics { + cpu: number; + memoryUsed: number; + memoryTotal: number; + diskUsed: number; + diskTotal: number; + networkRx: number; + networkTx: number; + uptime: number; +} \ No newline at end of file diff --git a/tailwind.config.ts b/tailwind.config.ts new file mode 100644 index 0000000..927ec3a --- /dev/null +++ b/tailwind.config.ts @@ -0,0 +1,30 @@ +import type { Config } from 'tailwindcss'; + +const config: Config = { + content: [ + './src/pages/**/*.{js,ts,jsx,tsx,mdx}', + './src/components/**/*.{js,ts,jsx,tsx,mdx}', + './src/app/**/*.{js,ts,jsx,tsx,mdx}' + ], + darkMode: 'class', + theme: { + extend: { + colors: { + background: '#0B1120', + foreground: '#F9FAFB', + card: '#111827', + border: '#374151', + muted: '#9CA3AF', + primary: '#3B82F6', + accent: '#3B82F6', + destructive: '#EF4444' + }, + fontFamily: { + sans: ['Inter', 'system-ui', 'sans-serif'] + } + } + }, + plugins: [] +}; + +export default config; \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..c0eadb8 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compilerOptions": { + "target": "ES2020", + "lib": ["dom", "dom.iterable", "es6"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noImplicitAny": true, + "strictNullChecks": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +} \ No newline at end of file From ab58f27faadbe5b4917580976fc41d34c2b402a5 Mon Sep 17 00:00:00 2001 From: ibuzzardo Date: Mon, 2 Mar 2026 10:14:34 +1100 Subject: [PATCH 2/2] feat: [Dark Factory] Scaffold a responsive dark-themed Next.js 15 dashboard (VPS Command Center) with initial API route and system metric types. Generated by Dark Factory v4 pipeline job cmm8cqfch0002ykwinlr4p6r3 --- .env.example | 2 +- .gitignore | 13 +-- next.config.js | 11 +-- package.json | 14 +-- postcss.config.js | 6 +- src/app/api/system/route.ts | 37 ++++---- src/app/globals.css | 36 ++----- src/app/layout.tsx | 24 ++--- src/app/page.tsx | 182 +++++++++++++++++++----------------- src/lib/types.ts | 15 +-- tailwind.config.ts | 24 +++-- tsconfig.json | 7 +- 12 files changed, 178 insertions(+), 193 deletions(-) diff --git a/.env.example b/.env.example index 7ec6f0a..fa5d4f2 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1,2 @@ -VPS_API_KEY=your-api-key-here +VPS_API_KEY=your-key-here PORT=4002 \ No newline at end of file diff --git a/.gitignore b/.gitignore index a8dfcf7..894f99c 100644 --- a/.gitignore +++ b/.gitignore @@ -20,8 +20,7 @@ dist/ npm-debug.log* yarn-debug.log* yarn-error.log* -pnpm-debug.log* -lerna-debug.log* +*.log # Runtime data pids @@ -31,16 +30,14 @@ pids # Coverage directory used by tools like istanbul coverage/ -*.lcov # nyc test coverage .nyc_output +# IDE +.vscode/ +.idea/ + # OS .DS_Store -.DS_Store? -._* -.Spotlight-V100 -.Trashes -ehthumbs.db Thumbs.db \ No newline at end of file diff --git a/next.config.js b/next.config.js index b6ffb64..3c543bb 100644 --- a/next.config.js +++ b/next.config.js @@ -1,12 +1,9 @@ /** @type {import('next').NextConfig} */ const nextConfig = { - output: 'standalone', + reactStrictMode: true, experimental: { - typedRoutes: true - }, - env: { - PORT: process.env.PORT || '4002' + appDir: true } -}; +} -module.exports = nextConfig; \ No newline at end of file +module.exports = nextConfig \ No newline at end of file diff --git a/package.json b/package.json index 47d4a61..5368a12 100644 --- a/package.json +++ b/package.json @@ -10,18 +10,20 @@ }, "dependencies": { "next": "^15.0.0", - "react": "^18.0.0", - "react-dom": "^18.0.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", "systeminformation": "^5.21.20", "zod": "^3.22.4" }, "devDependencies": { - "@types/node": "^20.0.0", - "@types/react": "^18.0.0", - "@types/react-dom": "^18.0.0", + "@types/node": "^20.8.0", + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.0", "autoprefixer": "^10.4.16", + "eslint": "^8.51.0", + "eslint-config-next": "^15.0.0", "postcss": "^8.4.31", "tailwindcss": "^3.3.5", - "typescript": "^5.0.0" + "typescript": "^5.2.2" } } \ No newline at end of file diff --git a/postcss.config.js b/postcss.config.js index 7fbaf2a..96bb01e 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,6 +1,6 @@ module.exports = { plugins: { tailwindcss: {}, - autoprefixer: {} - } -}; \ No newline at end of file + autoprefixer: {}, + }, +} \ No newline at end of file diff --git a/src/app/api/system/route.ts b/src/app/api/system/route.ts index a2a5279..50f879a 100644 --- a/src/app/api/system/route.ts +++ b/src/app/api/system/route.ts @@ -1,6 +1,6 @@ -import { NextResponse } from 'next/server'; -import * as si from 'systeminformation'; -import type { SystemMetrics } from '@/lib/types'; +import { NextResponse } from 'next/server' +import * as si from 'systeminformation' +import { SystemMetrics } from '@/lib/types' export async function GET(): Promise> { try { @@ -9,29 +9,30 @@ export async function GET(): Promise 0 ? disk[0].use : 0, + network: { + rx: network.length > 0 ? network[0].rx_bytes : 0, + tx: network.length > 0 ? network[0].tx_bytes : 0 + }, uptime: uptime - }; + } - return NextResponse.json(metrics); + return NextResponse.json(metrics) } catch (error) { - console.error('System metrics error:', error); + console.error('Error fetching system metrics:', error) return NextResponse.json( { error: 'Failed to fetch system metrics' }, { status: 500 } - ); + ) } } \ No newline at end of file diff --git a/src/app/globals.css b/src/app/globals.css index 45e4ff3..44a4f8c 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -3,42 +3,18 @@ @tailwind utilities; :root { - --background: #0B1120; - --foreground: #F9FAFB; - --card: #111827; - --card-foreground: #F9FAFB; - --border: #374151; - --muted: #9CA3AF; - --muted-foreground: #9CA3AF; --primary: #3B82F6; - --primary-foreground: #F9FAFB; - --accent: #3B82F6; - --accent-foreground: #F9FAFB; - --destructive: #EF4444; - --destructive-foreground: #F9FAFB; -} - -.dark { + --secondary: #9CA3AF; --background: #0B1120; --foreground: #F9FAFB; - --card: #111827; - --card-foreground: #F9FAFB; - --border: #374151; - --muted: #9CA3AF; - --muted-foreground: #9CA3AF; - --primary: #3B82F6; - --primary-foreground: #F9FAFB; + --muted: #374151; --accent: #3B82F6; - --accent-foreground: #F9FAFB; --destructive: #EF4444; - --destructive-foreground: #F9FAFB; -} - -* { - border-color: hsl(var(--border)); + --card: #111827; } body { - color: hsl(var(--foreground)); - background: hsl(var(--background)); + font-family: 'Inter', system-ui, sans-serif; + background-color: var(--background); + color: var(--foreground); } \ No newline at end of file diff --git a/src/app/layout.tsx b/src/app/layout.tsx index e135e80..ce0a78e 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,24 +1,24 @@ -import type { Metadata } from 'next'; -import { Inter } from 'next/font/google'; -import './globals.css'; +import type { Metadata } from 'next' +import { Inter } from 'next/font/google' +import './globals.css' -const inter = Inter({ subsets: ['latin'] }); +const inter = Inter({ subsets: ['latin'] }) export const metadata: Metadata = { title: 'VPS Command Center', - description: 'Self-hosted VPS monitoring dashboard' -}; + description: 'Self-hosted VPS monitoring dashboard', +} export default function RootLayout({ - children + children, }: { - children: React.ReactNode; + children: React.ReactNode }): JSX.Element { return ( - - -
{children}
+ + + {children} - ); + ) } \ No newline at end of file diff --git a/src/app/page.tsx b/src/app/page.tsx index 3b971a7..50cf0be 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,109 +1,123 @@ -'use client'; +'use client' -import { useEffect, useState } from 'react'; -import type { SystemMetrics } from '@/lib/types'; - -function formatBytes(bytes: number): string { - const gb = bytes / (1024 * 1024 * 1024); - return `${gb.toFixed(1)} GB`; -} - -function formatUptime(seconds: number): string { - const days = Math.floor(seconds / 86400); - const hours = Math.floor((seconds % 86400) / 3600); - const minutes = Math.floor((seconds % 3600) / 60); - return `${days}d ${hours}h ${minutes}m`; -} +import { useEffect, useState } from 'react' +import { SystemMetrics } from '@/lib/types' export default function Dashboard(): JSX.Element { - const [metrics, setMetrics] = useState(null); - const [loading, setLoading] = useState(true); + const [metrics, setMetrics] = useState(null) + const [loading, setLoading] = useState(true) + const [error, setError] = useState(null) - useEffect(() => { - const fetchMetrics = async (): Promise => { - try { - const response = await fetch('/api/system'); - if (response.ok) { - const data = await response.json(); - setMetrics(data); - } - } catch (error) { - console.error('Failed to fetch metrics:', error); - } finally { - setLoading(false); + const fetchMetrics = async (): Promise => { + try { + const response = await fetch('/api/system') + if (!response.ok) { + throw new Error('Failed to fetch metrics') } - }; + const data = await response.json() + setMetrics(data) + setError(null) + } catch (err) { + setError(err instanceof Error ? err.message : 'Unknown error') + } finally { + setLoading(false) + } + } + + useEffect(() => { + fetchMetrics() + const interval = setInterval(fetchMetrics, 3000) + return () => clearInterval(interval) + }, []) - fetchMetrics(); - const interval = setInterval(fetchMetrics, 3000); + const formatBytes = (bytes: number): string => { + const gb = bytes / (1024 * 1024 * 1024) + return `${gb.toFixed(2)} GB` + } - return () => clearInterval(interval); - }, []); + const formatUptime = (seconds: number): string => { + const days = Math.floor(seconds / 86400) + const hours = Math.floor((seconds % 86400) / 3600) + const minutes = Math.floor((seconds % 3600) / 60) + return `${days}d ${hours}h ${minutes}m` + } if (loading) { return ( -
-

VPS Command Center

-
- {Array.from({ length: 6 }).map((_, i) => ( -
-
-
-
-
-
- ))} -
+
+
Loading system metrics...
- ); + ) + } + + if (error) { + return ( +
+
Error: {error}
+
+ ) } return ( -
+

VPS Command Center

+
-
-

CPU Usage

-

- {metrics?.cpu ?? 'TODO'}% -

+ {/* CPU Usage */} +
+

CPU Usage

+
+ {metrics?.cpu.toFixed(1)}% +
- -
-

Memory

-

- {metrics ? `${formatBytes(metrics.memoryUsed)} / ${formatBytes(metrics.memoryTotal)}` : 'TODO'} -

+ + {/* Memory Usage */} +
+

Memory

+
+ {metrics ? formatBytes(metrics.memory.used) : '0 GB'} +
+
+ of {metrics ? formatBytes(metrics.memory.total) : '0 GB'} +
- -
-

Disk Usage

-

- {metrics ? `${formatBytes(metrics.diskUsed)} / ${formatBytes(metrics.diskTotal)}` : 'TODO'} -

+ + {/* Disk Usage */} +
+

Disk Usage

+
+ {metrics?.disk.toFixed(1)}% +
- -
-

Network RX

-

- {metrics ? formatBytes(metrics.networkRx) : 'TODO'} -

+ + {/* Network RX */} +
+

Network RX

+
+ {metrics ? formatBytes(metrics.network.rx) : '0 GB'} +
- -
-

Network TX

-

- {metrics ? formatBytes(metrics.networkTx) : 'TODO'} -

+ + {/* Network TX */} +
+

Network TX

+
+ {metrics ? formatBytes(metrics.network.tx) : '0 GB'} +
- -
-

Uptime

-

- {metrics ? formatUptime(metrics.uptime) : 'TODO'} -

+ + {/* Uptime */} +
+

Uptime

+
+ {metrics ? formatUptime(metrics.uptime) : '0d 0h 0m'} +
+ + {/* TODO: Sprint 2 - Add PM2 process management */} + {/* TODO: Sprint 2 - Add deployed projects section */} + {/* TODO: Sprint 2 - Add web terminal */}
- ); + ) } \ No newline at end of file diff --git a/src/lib/types.ts b/src/lib/types.ts index 700af49..48bf0e6 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -1,10 +1,13 @@ export interface SystemMetrics { cpu: number; - memoryUsed: number; - memoryTotal: number; - diskUsed: number; - diskTotal: number; - networkRx: number; - networkTx: number; + memory: { + used: number; + total: number; + }; + disk: number; + network: { + rx: number; + tx: number; + }; uptime: number; } \ No newline at end of file diff --git a/tailwind.config.ts b/tailwind.config.ts index 927ec3a..384cd23 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -1,30 +1,28 @@ -import type { Config } from 'tailwindcss'; +import type { Config } from 'tailwindcss' const config: Config = { content: [ './src/pages/**/*.{js,ts,jsx,tsx,mdx}', './src/components/**/*.{js,ts,jsx,tsx,mdx}', - './src/app/**/*.{js,ts,jsx,tsx,mdx}' + './src/app/**/*.{js,ts,jsx,tsx,mdx}', ], - darkMode: 'class', theme: { extend: { colors: { + primary: '#3B82F6', + secondary: '#9CA3AF', background: '#0B1120', foreground: '#F9FAFB', - card: '#111827', - border: '#374151', - muted: '#9CA3AF', - primary: '#3B82F6', + muted: '#374151', accent: '#3B82F6', - destructive: '#EF4444' + destructive: '#EF4444', + card: '#111827' }, fontFamily: { sans: ['Inter', 'system-ui', 'sans-serif'] } - } + }, }, - plugins: [] -}; - -export default config; \ No newline at end of file + plugins: [], +} +export default config \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index c0eadb8..b1814a0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,17 +1,14 @@ { "compilerOptions": { - "target": "ES2020", + "target": "es5", "lib": ["dom", "dom.iterable", "es6"], "allowJs": true, "skipLibCheck": true, "strict": true, - "noImplicitAny": true, - "strictNullChecks": true, - "forceConsistentCasingInFileNames": true, "noEmit": true, "esModuleInterop": true, "module": "esnext", - "moduleResolution": "node", + "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve",