init project structer

This commit is contained in:
2025-10-08 14:12:48 +07:00
commit 9c177abda0
22 changed files with 6737 additions and 0 deletions

4
apps/web/.eslintrc.json Normal file
View File

@@ -0,0 +1,4 @@
{
"extends": "next/core-web-vitals"
}

5
apps/web/next-env.d.ts vendored Normal file
View File

@@ -0,0 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.

21
apps/web/next.config.js Normal file
View File

@@ -0,0 +1,21 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
// Static Export - Build to pure HTML/CSS/JS
output: 'export',
// Disable features not supported in static export
images: {
unoptimized: true,
},
// Optional: add trailing slash
trailingSlash: true,
// Optional: if Go serves from /app path
// basePath: '/app',
}
module.exports = nextConfig

27
apps/web/package.json Normal file
View File

@@ -0,0 +1,27 @@
{
"name": "@catsave/web",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"lint": "next lint"
},
"dependencies": {
"next": "^14.2.5",
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
"devDependencies": {
"@types/node": "^20.14.12",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"autoprefixer": "^10.4.19",
"eslint": "^8.57.0",
"eslint-config-next": "^14.2.5",
"postcss": "^8.4.39",
"tailwindcss": "^3.4.6",
"typescript": "^5.5.4"
}
}

View File

@@ -0,0 +1,10 @@
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
export default config;

View File

@@ -0,0 +1,24 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
max-width: 100vw;
overflow-x: hidden;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

View File

@@ -0,0 +1,20 @@
import type { Metadata } from 'next'
import './globals.css'
export const metadata: Metadata = {
title: 'CatSave',
description: 'Go + Next.js Single Binary Application',
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}

72
apps/web/src/app/page.tsx Normal file
View File

@@ -0,0 +1,72 @@
'use client'
import { useState, useEffect } from 'react'
export default function Home() {
const [apiData, setApiData] = useState<any>(null)
useEffect(() => {
// Call Go API
fetch('/api/health')
.then(res => res.json())
.then(data => setApiData(data))
.catch(err => console.error(err))
}, [])
return (
<main className="min-h-screen bg-gradient-to-br from-gray-50 via-blue-50 to-indigo-50 flex items-center justify-center p-6">
<div className="max-w-2xl w-full">
<div className="text-center mb-8">
<div className="inline-flex items-center justify-center w-20 h-20 bg-gradient-to-br from-blue-500 to-indigo-600 rounded-3xl shadow-lg mb-6">
<span className="text-5xl">🐱</span>
</div>
<h1 className="text-5xl font-bold text-gray-900 mb-4">
CatSave
</h1>
<p className="text-xl text-gray-600 mb-8">
Go + Next.js Single Binary
</p>
</div>
<div className="bg-white rounded-3xl shadow-2xl p-8 space-y-6">
<div className="grid grid-cols-2 gap-4">
<div className="bg-gradient-to-br from-blue-50 to-indigo-50 rounded-xl p-6 border-2 border-blue-100">
<h3 className="text-lg font-bold text-gray-900 mb-2">Frontend</h3>
<p className="text-sm text-gray-600">Next.js 14 + React 18</p>
<p className="text-xs text-blue-600 mt-2"> Static Export</p>
</div>
<div className="bg-gradient-to-br from-green-50 to-emerald-50 rounded-xl p-6 border-2 border-green-100">
<h3 className="text-lg font-bold text-gray-900 mb-2">Backend</h3>
<p className="text-sm text-gray-600">Go 1.21+</p>
<p className="text-xs text-green-600 mt-2"> Embedded</p>
</div>
</div>
<div className="bg-gradient-to-br from-purple-50 to-pink-50 rounded-xl p-6 border-2 border-purple-100">
<h3 className="text-lg font-bold text-gray-900 mb-3">API Status</h3>
{apiData ? (
<div className="space-y-2 text-sm">
<p> Status: <span className="font-mono text-green-600">{apiData.status}</span></p>
<p> Time: <span className="font-mono text-gray-600">{apiData.timestamp}</span></p>
<p>🐹 Server: <span className="font-mono text-blue-600">{apiData.message}</span></p>
</div>
) : (
<p className="text-sm text-gray-500">Loading...</p>
)}
</div>
<div className="text-center pt-4">
<a
href="/setup"
className="inline-block px-8 py-3 bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-700 hover:to-indigo-700 text-white font-semibold rounded-xl shadow-lg transition-all"
>
Setup Wizard
</a>
</div>
</div>
</div>
</main>
)
}

View File

@@ -0,0 +1,25 @@
'use client'
export default function SetupPage() {
return (
<div className="min-h-screen bg-gradient-to-br from-gray-50 via-blue-50 to-indigo-50 flex items-center justify-center p-6">
<div className="max-w-2xl w-full">
<div className="bg-white rounded-3xl shadow-2xl p-8">
<h1 className="text-3xl font-bold text-gray-900 mb-4">
Setup Wizard
</h1>
<p className="text-gray-600 mb-6">
Configuration page coming soon...
</p>
<a
href="/"
className="inline-block px-6 py-2 bg-gray-200 hover:bg-gray-300 text-gray-800 font-medium rounded-lg transition-all"
>
Back to Home
</a>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,16 @@
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}",
],
theme: {
extend: {},
},
plugins: [],
};
export default config;

28
apps/web/tsconfig.json Normal file
View File

@@ -0,0 +1,28 @@
{
"compilerOptions": {
"target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}