From 043f4b5da941531a680b9cc98a973bfcca9c8846 Mon Sep 17 00:00:00 2001 From: truthwing Date: Thu, 6 Mar 2025 18:25:20 +0900 Subject: [PATCH] init --- apps/sn/.gitignore | 41 ++++ apps/sn/.prettierrc | 3 + apps/sn/app/layout.tsx | 8 + apps/sn/app/site/page.tsx | 2 + apps/sn/app/site/register/page.tsx | 2 + apps/sn/eslint.config.mjs | 16 ++ apps/sn/next.config.ts | 5 + apps/sn/package.json | 27 +++ apps/sn/pages/.gitkeep | 0 apps/sn/postcss.config.mjs | 8 + apps/sn/src/app/index.tsx | 12 ++ apps/sn/src/app/styles/base.css | 11 + apps/sn/src/app/styles/components.css | 16 ++ apps/sn/src/pages/site/index.ts | 2 + apps/sn/src/pages/site/model/__mocks__.tsx | 59 ++++++ apps/sn/src/pages/site/ui/layout.tsx | 16 ++ apps/sn/src/pages/site/ui/register-page.tsx | 216 ++++++++++++++++++++ apps/sn/src/pages/site/ui/site-page.tsx | 38 ++++ apps/sn/tailwind.config.ts | 18 ++ apps/sn/tsconfig.json | 45 ++++ 20 files changed, 545 insertions(+) create mode 100644 apps/sn/.gitignore create mode 100644 apps/sn/.prettierrc create mode 100644 apps/sn/app/layout.tsx create mode 100644 apps/sn/app/site/page.tsx create mode 100644 apps/sn/app/site/register/page.tsx create mode 100644 apps/sn/eslint.config.mjs create mode 100644 apps/sn/next.config.ts create mode 100644 apps/sn/package.json create mode 100644 apps/sn/pages/.gitkeep create mode 100644 apps/sn/postcss.config.mjs create mode 100644 apps/sn/src/app/index.tsx create mode 100644 apps/sn/src/app/styles/base.css create mode 100644 apps/sn/src/app/styles/components.css create mode 100644 apps/sn/src/pages/site/index.ts create mode 100644 apps/sn/src/pages/site/model/__mocks__.tsx create mode 100644 apps/sn/src/pages/site/ui/layout.tsx create mode 100644 apps/sn/src/pages/site/ui/register-page.tsx create mode 100644 apps/sn/src/pages/site/ui/site-page.tsx create mode 100644 apps/sn/tailwind.config.ts create mode 100644 apps/sn/tsconfig.json diff --git a/apps/sn/.gitignore b/apps/sn/.gitignore new file mode 100644 index 000000000..5ef6a5207 --- /dev/null +++ b/apps/sn/.gitignore @@ -0,0 +1,41 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files (can opt-in for committing if needed) +.env* + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/apps/sn/.prettierrc b/apps/sn/.prettierrc new file mode 100644 index 000000000..b4bfed357 --- /dev/null +++ b/apps/sn/.prettierrc @@ -0,0 +1,3 @@ +{ + "plugins": ["prettier-plugin-tailwindcss"] +} diff --git a/apps/sn/app/layout.tsx b/apps/sn/app/layout.tsx new file mode 100644 index 000000000..aa2049dcc --- /dev/null +++ b/apps/sn/app/layout.tsx @@ -0,0 +1,8 @@ +import type { Metadata } from "next"; +import { App } from "@/app"; + +export const metadata: Metadata = { + title: "유역하수도 통합 정보플랫폼", +}; + +export default App; diff --git a/apps/sn/app/site/page.tsx b/apps/sn/app/site/page.tsx new file mode 100644 index 000000000..0cf120630 --- /dev/null +++ b/apps/sn/app/site/page.tsx @@ -0,0 +1,2 @@ +import { SitePage } from "@/pages/site"; +export default SitePage; diff --git a/apps/sn/app/site/register/page.tsx b/apps/sn/app/site/register/page.tsx new file mode 100644 index 000000000..a11d0b60c --- /dev/null +++ b/apps/sn/app/site/register/page.tsx @@ -0,0 +1,2 @@ +import { RegisterPage } from "@/pages/site"; +export default RegisterPage; diff --git a/apps/sn/eslint.config.mjs b/apps/sn/eslint.config.mjs new file mode 100644 index 000000000..c85fb67c4 --- /dev/null +++ b/apps/sn/eslint.config.mjs @@ -0,0 +1,16 @@ +import { dirname } from "path"; +import { fileURLToPath } from "url"; +import { FlatCompat } from "@eslint/eslintrc"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +const compat = new FlatCompat({ + baseDirectory: __dirname, +}); + +const eslintConfig = [ + ...compat.extends("next/core-web-vitals", "next/typescript"), +]; + +export default eslintConfig; diff --git a/apps/sn/next.config.ts b/apps/sn/next.config.ts new file mode 100644 index 000000000..cb651cdc0 --- /dev/null +++ b/apps/sn/next.config.ts @@ -0,0 +1,5 @@ +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = {}; + +export default nextConfig; diff --git a/apps/sn/package.json b/apps/sn/package.json new file mode 100644 index 000000000..0c125f73e --- /dev/null +++ b/apps/sn/package.json @@ -0,0 +1,27 @@ +{ + "name": "sn", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "NODE_OPTIONS='--inspect' next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "@common/business_components": "workspace:*", + "@common/components": "workspace:*", + "next": "15.1.7", + "zod": "^3.24.2", + "@hookform/resolvers": "^4.1.3", + "react-hook-form": "^7.54.2" + }, + "devDependencies": { + "@eslint/eslintrc": "^3", + "eslint": "^9", + "eslint-config-next": "15.1.7", + "postcss": "^8", + "tailwindcss": "^3.4.1", + "typescript": "^5" + } +} diff --git a/apps/sn/pages/.gitkeep b/apps/sn/pages/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/apps/sn/postcss.config.mjs b/apps/sn/postcss.config.mjs new file mode 100644 index 000000000..1a69fd2a4 --- /dev/null +++ b/apps/sn/postcss.config.mjs @@ -0,0 +1,8 @@ +/** @type {import('postcss-load-config').Config} */ +const config = { + plugins: { + tailwindcss: {}, + }, +}; + +export default config; diff --git a/apps/sn/src/app/index.tsx b/apps/sn/src/app/index.tsx new file mode 100644 index 000000000..9223b0790 --- /dev/null +++ b/apps/sn/src/app/index.tsx @@ -0,0 +1,12 @@ +import "./styles/base.css"; +import "./styles/components.css"; + +const App = ({ children }: Readonly<{ children: React.ReactNode }>) => { + return ( + + {children} + + ); +}; + +export { App }; diff --git a/apps/sn/src/app/styles/base.css b/apps/sn/src/app/styles/base.css new file mode 100644 index 000000000..e24111afe --- /dev/null +++ b/apps/sn/src/app/styles/base.css @@ -0,0 +1,11 @@ +@import "@common/assets/styles/base.css"; +@import "@common/assets/styles/diveicon.css"; + +@tailwind base; +@tailwind utilities; + +html, +body { + font-family: "Noto Sans KR", sans-serif; + font-size: 10px; +} diff --git a/apps/sn/src/app/styles/components.css b/apps/sn/src/app/styles/components.css new file mode 100644 index 000000000..4d5caaf96 --- /dev/null +++ b/apps/sn/src/app/styles/components.css @@ -0,0 +1,16 @@ +@tailwind components; + +@layer components { + .card { + @apply relative m-[0.6rem] box-border min-h-[2rem] rounded-[0.5rem] p-[0.6rem] text-[1.3rem] text-[#666]; + } + .card-border { + @apply shadow-blur border border-[#dbe2e6] bg-[rgba(255,255,255,0.6)]; + } + .card-header { + @apply -mx-[0.6rem] flex items-center justify-between border-b border-b-[#e1e7eb] p-4; + } + .card-footer { + @apply -mx-[0.6rem] mt-2 flex items-center justify-center border-t border-t-[#e1e7eb] py-4; + } +} diff --git a/apps/sn/src/pages/site/index.ts b/apps/sn/src/pages/site/index.ts new file mode 100644 index 000000000..22c7fef7b --- /dev/null +++ b/apps/sn/src/pages/site/index.ts @@ -0,0 +1,2 @@ +export { RegisterPage } from "./ui/register-page"; +export { SitePage } from "./ui/site-page"; diff --git a/apps/sn/src/pages/site/model/__mocks__.tsx b/apps/sn/src/pages/site/model/__mocks__.tsx new file mode 100644 index 000000000..1d11afa9a --- /dev/null +++ b/apps/sn/src/pages/site/model/__mocks__.tsx @@ -0,0 +1,59 @@ +import { createColumnHelper } from "@tanstack/react-table"; +import { fakerKO as faker } from "@faker-js/faker"; + +type Site = { + id: number; + 사이트코드: string; + 사이트명: string; + 대표_URL: string; + 기본_사이트_여부: boolean; + 사용_여부: boolean; + 등록자: string; + 등록일: string; +}; + +faker.seed(123); + +const data: Site[] = Array.from({ length: 100 }, (_, i) => ({ + id: i + 1, + 사이트코드: faker.string.alpha(2).toUpperCase(), + 사이트명: faker.lorem.word(), + 대표_URL: faker.internet.url(), + 기본_사이트_여부: faker.datatype.boolean(), + 사용_여부: faker.datatype.boolean(), + 등록자: faker.person.fullName(), + 등록일: faker.date.recent().toISOString().split("T")[0] as string, +})); + +const columnHelper = createColumnHelper(); + +const columns = [ + columnHelper.accessor("id", { + header: "NO", + }), + columnHelper.accessor("사이트코드", { + header: "사이트코드", + }), + columnHelper.accessor("사이트명", { + header: "사이트명", + }), + columnHelper.accessor("대표_URL", { + header: "대표_URL", + }), + columnHelper.accessor("기본_사이트_여부", { + header: "기본 사이트 여부", + cell: (info) => (info.getValue() ? "Y" : "N"), + }), + columnHelper.accessor("사용_여부", { + header: "사용 여부", + cell: (info) => (info.getValue() ? "Y" : "N"), + }), + columnHelper.accessor("등록자", { + header: "등록자", + }), + columnHelper.accessor("등록일", { + header: "등록일", + }), +]; + +export { data, columns }; diff --git a/apps/sn/src/pages/site/ui/layout.tsx b/apps/sn/src/pages/site/ui/layout.tsx new file mode 100644 index 000000000..19e48fbd0 --- /dev/null +++ b/apps/sn/src/pages/site/ui/layout.tsx @@ -0,0 +1,16 @@ +import { BaseLayout } from "@common/components"; + +function SitePageLayout({ children }: { children: React.ReactNode }) { + return ( + +
+

+ 사이트 관리 +

+ {children} +
+
+ ); +} + +export { SitePageLayout }; diff --git a/apps/sn/src/pages/site/ui/register-page.tsx b/apps/sn/src/pages/site/ui/register-page.tsx new file mode 100644 index 000000000..e970b2de7 --- /dev/null +++ b/apps/sn/src/pages/site/ui/register-page.tsx @@ -0,0 +1,216 @@ +import { + Button, + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, + Input, + Label, + RadioGroup, + RadioGroupItem, + Table, + TableBody, + TableCell, + TableHead, + TableRow, +} from "@common/components"; +import { SitePageLayout } from "./layout"; + +function RegisterPage() { + return ( + +
+
+

사이트 등록/수정

+
+
+ + + + + 사이트 코드 + + + + + + + + 사이트 구분 + + +
+ + + + + + + 내부 + 외부 + + + + +
+
+
+ + + 사이트 디자인 + + + + + + + + + 라이트 + 다크 + + + + + + + + 사이트명 + + + + + + + + 사이트 설명 + + + + + + + + 사이트 하단 표기 주소 + + + + + + + + 사이트 하단 표기 전화번호 + + + + + + + + 사이트 하단 표기 팩스번호 + + + + + + + + 사이트 하단 표기 내용 + + + + + + + + 북마크 아이콘 + + + + + + + + 기본 사이트 여부 + + + +
+ + +
+
+ + +
+
+
+
+ + + 사용 여부 + + + +
+ + +
+
+ + +
+
+
+
+
+
+
+
+
+ + + +
+
+ ); +} + +export { RegisterPage }; diff --git a/apps/sn/src/pages/site/ui/site-page.tsx b/apps/sn/src/pages/site/ui/site-page.tsx new file mode 100644 index 000000000..d6efc8e15 --- /dev/null +++ b/apps/sn/src/pages/site/ui/site-page.tsx @@ -0,0 +1,38 @@ +"use client"; + +import "@common/assets/styles/grid.css"; + +import { useRouter } from "next/navigation"; +import { Button, Input } from "@common/components"; +import { SitePageLayout } from "./layout"; + +function SitePage() { + const router = useRouter(); + + return ( + +
+
+
+ + + +
+
+
+
+

사이트 목록

+ +
+
+ {/* */} +
+
+
+
+ ); +} + +export { SitePage }; diff --git a/apps/sn/tailwind.config.ts b/apps/sn/tailwind.config.ts new file mode 100644 index 000000000..3383e603d --- /dev/null +++ b/apps/sn/tailwind.config.ts @@ -0,0 +1,18 @@ +import type { Config } from "tailwindcss"; +import presetConfig from "../../tailwind.config.preset"; + +export default { + presets: [presetConfig], + darkMode: ["class", "[data-mode='dark']"], + content: [ + "./src/**/*.{js,ts,jsx,tsx,mdx}", + "../../packages/common/components/src/ui/**/*.{js,ts,jsx,tsx,mdx}", + ], + theme: { + extend: { + boxShadow: { + blur: "0 0 10px -1px rgba(0, 0, 0, 0.06)", + }, + }, + }, +} satisfies Config; diff --git a/apps/sn/tsconfig.json b/apps/sn/tsconfig.json new file mode 100644 index 000000000..3a9bab950 --- /dev/null +++ b/apps/sn/tsconfig.json @@ -0,0 +1,45 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "target": "ES2017", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "verbatimModuleSyntax": true, + "strictNullChecks": true, + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "baseUrl": "./src", + "paths": { + "@/*": ["./*"], + "@common/components": ["../../../packages/common/components/src"] + } + }, + "include": [ + ".eslintrc.*", + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + "**/*.mts", + "**/*.js", + "**/*.cjs", + "**/*.mjs", + "**/*.jsx", + "**/*.json", + ".next/types/**/*.ts" + ], + "exclude": ["**/node_modules", "**/.*/*"] +}