@farmzone/fz-template-react 1.0.6 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +102 -102
  2. package/bin/create.js +108 -108
  3. package/package.json +24 -24
  4. package/template/.env.example +5 -5
  5. package/template/.prettierrc +9 -9
  6. package/template/eslint.config.js +26 -26
  7. package/template/index.css +32 -32
  8. package/template/index.html +19 -19
  9. package/template/package.json +54 -54
  10. package/template/pnpm-lock.yaml +4214 -4214
  11. package/template/public/mockServiceWorker.js +349 -349
  12. package/template/src/app/App.tsx +26 -26
  13. package/template/src/app/api/api.ts +178 -178
  14. package/template/src/app/api/queries.ts +335 -335
  15. package/template/src/app/api/queryKey.ts +7 -7
  16. package/template/src/app/api/token.ts +8 -7
  17. package/template/src/app/layout/Layout.tsx +33 -33
  18. package/template/src/app/layout/ListContents.tsx +9 -9
  19. package/template/src/app/layout/ListHeader.tsx +41 -41
  20. package/template/src/app/layout/MultiTabNav.tsx +106 -101
  21. package/template/src/app/layout/Sidebar.tsx +33 -33
  22. package/template/src/app/layout/UserInfo.tsx +95 -94
  23. package/template/src/app/layout/menu.ts +79 -55
  24. package/template/src/app/layout/tabSwitchStore.ts +11 -11
  25. package/template/src/app/router/Router.tsx +56 -56
  26. package/template/src/app/store/index.ts +26 -26
  27. package/template/src/index.tsx +21 -21
  28. package/template/src/mocks/browser.ts +17 -17
  29. package/template/src/mocks/handlers.ts +43 -43
  30. package/template/src/mocks/scenarios.ts +57 -57
  31. package/template/src/pages/dashboard/index.tsx +541 -541
  32. package/template/src/pages/error/Error.tsx +29 -29
  33. package/template/src/pages/error/NotFound.tsx +27 -27
  34. package/template/src/pages/login/index.tsx +317 -317
  35. package/template/src/pages/post/PostFormModal.tsx +128 -128
  36. package/template/src/pages/post/detail/index.tsx +545 -545
  37. package/template/src/pages/post/index.tsx +266 -266
  38. package/template/src/pages/sample/SampleFormModal.tsx +188 -188
  39. package/template/src/pages/sample/detail/index.tsx +551 -517
  40. package/template/src/pages/sample/index.tsx +298 -298
  41. package/template/src/pages/sample/modal/index.tsx +308 -308
  42. package/template/src/pages/system/log/index.tsx +173 -173
  43. package/template/src/pages/user/config/columns.tsx +102 -102
  44. package/template/src/pages/user/config/schema.ts +54 -54
  45. package/template/src/pages/user/index.tsx +704 -650
  46. package/template/src/shared/components/CommentInput.tsx +243 -243
  47. package/template/src/shared/components/FilePreviewCard.tsx +71 -71
  48. package/template/src/shared/config/text.ts +27 -27
  49. package/template/src/shared/config/type.ts +40 -40
  50. package/template/src/shared/utils/format.ts +11 -11
  51. package/template/src/types/auth.ts +10 -10
  52. package/template/src/types/comment.ts +33 -33
  53. package/template/src/types/common.ts +19 -19
  54. package/template/src/types/dashboard.ts +53 -53
  55. package/template/src/types/index.ts +16 -16
  56. package/template/src/types/log.ts +21 -21
  57. package/template/src/types/post.ts +32 -32
  58. package/template/src/types/sample.ts +33 -33
  59. package/template/src/types/user.ts +51 -51
  60. package/template/src/vite-env.d.ts +10 -10
  61. package/template/tsconfig.app.json +32 -32
  62. package/template/tsconfig.json +7 -7
  63. package/template/tsconfig.node.json +26 -26
  64. package/template/vite.config.ts +13 -13
package/README.md CHANGED
@@ -1,102 +1,102 @@
1
- # @farmzone/fz-template-react
2
-
3
- Farmzone React 프로젝트 보일러플레이트 생성 CLI.
4
-
5
- ## 사용법
6
-
7
- ```bash
8
- npx @farmzone/fz-template-react <프로젝트명>
9
- ```
10
-
11
- 예시:
12
-
13
- ```bash
14
- npx @farmzone/fz-template-react my-app
15
- cd my-app
16
- pnpm install
17
- pnpm dev
18
- ```
19
-
20
- 프로젝트명을 생략하면 대화형으로 입력을 받습니다.
21
-
22
- ```bash
23
- npx @farmzone/fz-template-react
24
- # 프로젝트 이름을 입력하세요: my-app
25
- ```
26
-
27
- ## 포함된 기술 스택
28
-
29
- | 항목 | 버전 |
30
- | --------------------- | ------- |
31
- | React | ^19 |
32
- | Vite | ^7 |
33
- | TypeScript | ~5.9 |
34
- | Tailwind CSS | ^4 |
35
- | React Router | ^7 |
36
- | TanStack Query | ^5 |
37
- | @farmzone/fz-react-ui | ^0.0.6 |
38
- | react-hook-form | ^7 |
39
- | zod | ^3 |
40
- | Zustand | ^5 |
41
- | axios | ^1 |
42
- | dayjs | ^1 |
43
- | MSW | ^2 |
44
- | lucide-react | ^1 |
45
-
46
- ## 메뉴 추가
47
-
48
- `src/app/layout/menu.ts`의 `MENU_SECTIONS` 배열에 추가:
49
-
50
- ```ts
51
- import type { MenuSection } from "@farmzone/fz-react-ui";
52
- import { LayoutDashboard, Users, FileText, ScrollText } from "lucide-react";
53
-
54
- export const MENU_SECTIONS: Array<MenuSection> = [
55
- {
56
- items: [
57
- { icon: LayoutDashboard, label: "대시보드", path: "/" },
58
- {
59
- icon: FileText,
60
- label: "게시글 관리",
61
- children: [{ label: "게시글 관리", path: "/post" }],
62
- },
63
- {
64
- icon: Users,
65
- label: "사용자 관리",
66
- children: [{ label: "사용자 관리", path: "/user" }],
67
- },
68
- ],
69
- },
70
- {
71
- title: "시스템",
72
- items: [{ icon: ScrollText, label: "로그 관리", path: "/system/log" }],
73
- },
74
- ];
75
- ```
76
-
77
- `children` 배열을 사용하면 아코디언 서브메뉴로 렌더링됩니다.
78
-
79
- ## 라우트 추가
80
-
81
- `src/app/router/Router.tsx`의 `children` 배열에 추가:
82
-
83
- ```tsx
84
- children: [
85
- { index: true, element: <DashboardPage /> },
86
- { path: "sample", element: <SamplePage /> },
87
- { path: "sample/modal", element: <SampleModalPage /> },
88
- { path: "sample/:id", element: <SampleDetailPage /> },
89
- { path: "post", element: <PostPage /> },
90
- { path: "post/:id", element: <PostDetailPage /> },
91
- { path: "user", element: <UserPage /> },
92
- { path: "system/log", element: <LogPage /> },
93
- ],
94
- ```
95
-
96
- `/login` 경로와 `authLoader`(토큰 미존재 시 `/login` 리다이렉트)는 Router.tsx에 이미 포함되어 있습니다.
97
-
98
- ## npm 배포
99
-
100
- ```bash
101
- npm publish --access public
102
- ```
1
+ # @farmzone/fz-template-react
2
+
3
+ Farmzone React 프로젝트 보일러플레이트 생성 CLI.
4
+
5
+ ## 사용법
6
+
7
+ ```bash
8
+ npx @farmzone/fz-template-react <프로젝트명>
9
+ ```
10
+
11
+ 예시:
12
+
13
+ ```bash
14
+ npx @farmzone/fz-template-react my-app
15
+ cd my-app
16
+ pnpm install
17
+ pnpm dev
18
+ ```
19
+
20
+ 프로젝트명을 생략하면 대화형으로 입력을 받습니다.
21
+
22
+ ```bash
23
+ npx @farmzone/fz-template-react
24
+ # 프로젝트 이름을 입력하세요: my-app
25
+ ```
26
+
27
+ ## 포함된 기술 스택
28
+
29
+ | 항목 | 버전 |
30
+ | --------------------- | ------- |
31
+ | React | ^19 |
32
+ | Vite | ^7 |
33
+ | TypeScript | ~5.9 |
34
+ | Tailwind CSS | ^4 |
35
+ | React Router | ^7 |
36
+ | TanStack Query | ^5 |
37
+ | @farmzone/fz-react-ui | ^0.0.6 |
38
+ | react-hook-form | ^7 |
39
+ | zod | ^3 |
40
+ | Zustand | ^5 |
41
+ | axios | ^1 |
42
+ | dayjs | ^1 |
43
+ | MSW | ^2 |
44
+ | lucide-react | ^1 |
45
+
46
+ ## 메뉴 추가
47
+
48
+ `src/app/layout/menu.ts`의 `MENU_SECTIONS` 배열에 추가:
49
+
50
+ ```ts
51
+ import type { MenuSection } from "@farmzone/fz-react-ui";
52
+ import { LayoutDashboard, Users, FileText, ScrollText } from "lucide-react";
53
+
54
+ export const MENU_SECTIONS: Array<MenuSection> = [
55
+ {
56
+ items: [
57
+ { icon: LayoutDashboard, label: "대시보드", path: "/" },
58
+ {
59
+ icon: FileText,
60
+ label: "게시글 관리",
61
+ children: [{ label: "게시글 관리", path: "/post" }],
62
+ },
63
+ {
64
+ icon: Users,
65
+ label: "사용자 관리",
66
+ children: [{ label: "사용자 관리", path: "/user" }],
67
+ },
68
+ ],
69
+ },
70
+ {
71
+ title: "시스템",
72
+ items: [{ icon: ScrollText, label: "로그 관리", path: "/system/log" }],
73
+ },
74
+ ];
75
+ ```
76
+
77
+ `children` 배열을 사용하면 아코디언 서브메뉴로 렌더링됩니다.
78
+
79
+ ## 라우트 추가
80
+
81
+ `src/app/router/Router.tsx`의 `children` 배열에 추가:
82
+
83
+ ```tsx
84
+ children: [
85
+ { index: true, element: <DashboardPage /> },
86
+ { path: "sample", element: <SamplePage /> },
87
+ { path: "sample/modal", element: <SampleModalPage /> },
88
+ { path: "sample/:id", element: <SampleDetailPage /> },
89
+ { path: "post", element: <PostPage /> },
90
+ { path: "post/:id", element: <PostDetailPage /> },
91
+ { path: "user", element: <UserPage /> },
92
+ { path: "system/log", element: <LogPage /> },
93
+ ],
94
+ ```
95
+
96
+ `/login` 경로와 `authLoader`(토큰 미존재 시 `/login` 리다이렉트)는 Router.tsx에 이미 포함되어 있습니다.
97
+
98
+ ## npm 배포
99
+
100
+ ```bash
101
+ npm publish --access public
102
+ ```
package/bin/create.js CHANGED
@@ -1,108 +1,108 @@
1
- #!/usr/bin/env node
2
-
3
- import { createInterface } from "readline";
4
- import {
5
- existsSync,
6
- mkdirSync,
7
- readdirSync,
8
- statSync,
9
- copyFileSync,
10
- readFileSync,
11
- writeFileSync,
12
- renameSync,
13
- } from "fs";
14
- import { join, dirname } from "path";
15
- import { fileURLToPath } from "url";
16
-
17
- const __dirname = dirname(fileURLToPath(import.meta.url));
18
-
19
- function prompt(question) {
20
- const rl = createInterface({ input: process.stdin, output: process.stdout });
21
- return new Promise((resolve) => {
22
- rl.question(question, (answer) => {
23
- rl.close();
24
- resolve(answer.trim());
25
- });
26
- });
27
- }
28
-
29
- function copyDir(src, dest) {
30
- mkdirSync(dest, { recursive: true });
31
- for (const entry of readdirSync(src)) {
32
- const srcPath = join(src, entry);
33
- const destPath = join(dest, entry);
34
- if (statSync(srcPath).isDirectory()) {
35
- copyDir(srcPath, destPath);
36
- } else {
37
- copyFileSync(srcPath, destPath);
38
- }
39
- }
40
- }
41
-
42
- function replaceInFile(filePath, search, replacement) {
43
- if (!existsSync(filePath)) return;
44
- const content = readFileSync(filePath, "utf-8");
45
- writeFileSync(filePath, content.replaceAll(search, replacement));
46
- }
47
-
48
- async function main() {
49
- console.log("\n🌱 Farmzone React Template\n");
50
-
51
- let projectName = process.argv[2];
52
-
53
- if (!projectName) {
54
- projectName = await prompt("프로젝트 이름을 입력하세요: ");
55
- }
56
-
57
- if (!projectName) {
58
- console.error("❌ 프로젝트 이름을 입력해야 합니다.");
59
- process.exit(1);
60
- }
61
-
62
- if (!/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(projectName)) {
63
- console.error(
64
- "❌ 프로젝트 이름은 소문자, 숫자, 하이픈(-)만 사용 가능하며 하이픈으로 시작하거나 끝날 수 없습니다.",
65
- );
66
- process.exit(1);
67
- }
68
-
69
- const targetDir = join(process.cwd(), projectName);
70
-
71
- if (existsSync(targetDir)) {
72
- console.error(`❌ '${projectName}' 디렉터리가 이미 존재합니다.`);
73
- process.exit(1);
74
- }
75
-
76
- const templateDir = join(__dirname, "..", "template");
77
-
78
- console.log(`\n🚀 '${projectName}' 프로젝트를 생성합니다...\n`);
79
-
80
- // 템플릿 복사
81
- copyDir(templateDir, targetDir);
82
-
83
- // gitignore -> .gitignore 이름 변경 (npm publish 시 .gitignore는 자동으로 제외됨)
84
- const gitignoreSrc = join(targetDir, "gitignore");
85
- const gitignoreDest = join(targetDir, ".gitignore");
86
- if (existsSync(gitignoreSrc)) renameSync(gitignoreSrc, gitignoreDest);
87
-
88
- // __PROJECT_NAME__ 치환
89
- replaceInFile(
90
- join(targetDir, "package.json"),
91
- "__PROJECT_NAME__",
92
- projectName,
93
- );
94
- replaceInFile(join(targetDir, "index.html"), "__PROJECT_NAME__", projectName);
95
-
96
- console.log("✅ 프로젝트 생성 완료!\n");
97
- console.log("──────────────────────────────");
98
- console.log("다음 명령어로 시작하세요:\n");
99
- console.log(` cd ${projectName}`);
100
- console.log(` pnpm install`);
101
- console.log(` pnpm run dev`);
102
- console.log("──────────────────────────────\n");
103
- }
104
-
105
- main().catch((err) => {
106
- console.error(err);
107
- process.exit(1);
108
- });
1
+ #!/usr/bin/env node
2
+
3
+ import { createInterface } from "readline";
4
+ import {
5
+ existsSync,
6
+ mkdirSync,
7
+ readdirSync,
8
+ statSync,
9
+ copyFileSync,
10
+ readFileSync,
11
+ writeFileSync,
12
+ renameSync,
13
+ } from "fs";
14
+ import { join, dirname } from "path";
15
+ import { fileURLToPath } from "url";
16
+
17
+ const __dirname = dirname(fileURLToPath(import.meta.url));
18
+
19
+ function prompt(question) {
20
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
21
+ return new Promise((resolve) => {
22
+ rl.question(question, (answer) => {
23
+ rl.close();
24
+ resolve(answer.trim());
25
+ });
26
+ });
27
+ }
28
+
29
+ function copyDir(src, dest) {
30
+ mkdirSync(dest, { recursive: true });
31
+ for (const entry of readdirSync(src)) {
32
+ const srcPath = join(src, entry);
33
+ const destPath = join(dest, entry);
34
+ if (statSync(srcPath).isDirectory()) {
35
+ copyDir(srcPath, destPath);
36
+ } else {
37
+ copyFileSync(srcPath, destPath);
38
+ }
39
+ }
40
+ }
41
+
42
+ function replaceInFile(filePath, search, replacement) {
43
+ if (!existsSync(filePath)) return;
44
+ const content = readFileSync(filePath, "utf-8");
45
+ writeFileSync(filePath, content.replaceAll(search, replacement));
46
+ }
47
+
48
+ async function main() {
49
+ console.log("\n🌱 Farmzone React Template\n");
50
+
51
+ let projectName = process.argv[2];
52
+
53
+ if (!projectName) {
54
+ projectName = await prompt("프로젝트 이름을 입력하세요: ");
55
+ }
56
+
57
+ if (!projectName) {
58
+ console.error("❌ 프로젝트 이름을 입력해야 합니다.");
59
+ process.exit(1);
60
+ }
61
+
62
+ if (!/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(projectName)) {
63
+ console.error(
64
+ "❌ 프로젝트 이름은 소문자, 숫자, 하이픈(-)만 사용 가능하며 하이픈으로 시작하거나 끝날 수 없습니다.",
65
+ );
66
+ process.exit(1);
67
+ }
68
+
69
+ const targetDir = join(process.cwd(), projectName);
70
+
71
+ if (existsSync(targetDir)) {
72
+ console.error(`❌ '${projectName}' 디렉터리가 이미 존재합니다.`);
73
+ process.exit(1);
74
+ }
75
+
76
+ const templateDir = join(__dirname, "..", "template");
77
+
78
+ console.log(`\n🚀 '${projectName}' 프로젝트를 생성합니다...\n`);
79
+
80
+ // 템플릿 복사
81
+ copyDir(templateDir, targetDir);
82
+
83
+ // gitignore -> .gitignore 이름 변경 (npm publish 시 .gitignore는 자동으로 제외됨)
84
+ const gitignoreSrc = join(targetDir, "gitignore");
85
+ const gitignoreDest = join(targetDir, ".gitignore");
86
+ if (existsSync(gitignoreSrc)) renameSync(gitignoreSrc, gitignoreDest);
87
+
88
+ // __PROJECT_NAME__ 치환
89
+ replaceInFile(
90
+ join(targetDir, "package.json"),
91
+ "__PROJECT_NAME__",
92
+ projectName,
93
+ );
94
+ replaceInFile(join(targetDir, "index.html"), "__PROJECT_NAME__", projectName);
95
+
96
+ console.log("✅ 프로젝트 생성 완료!\n");
97
+ console.log("──────────────────────────────");
98
+ console.log("다음 명령어로 시작하세요:\n");
99
+ console.log(` cd ${projectName}`);
100
+ console.log(` pnpm install`);
101
+ console.log(` pnpm run dev`);
102
+ console.log("──────────────────────────────\n");
103
+ }
104
+
105
+ main().catch((err) => {
106
+ console.error(err);
107
+ process.exit(1);
108
+ });
package/package.json CHANGED
@@ -1,24 +1,24 @@
1
- {
2
- "name": "@farmzone/fz-template-react",
3
- "version": "1.0.6",
4
- "description": "Farmzone React 프로젝트 보일러플레이트 생성 CLI",
5
- "type": "module",
6
- "bin": {
7
- "fz-template-react": "./bin/create.js"
8
- },
9
- "files": [
10
- "bin",
11
- "template"
12
- ],
13
- "keywords": [
14
- "farmzone",
15
- "react",
16
- "template",
17
- "boilerplate",
18
- "vite"
19
- ],
20
- "license": "UNLICENSED",
21
- "engines": {
22
- "node": ">=18"
23
- }
24
- }
1
+ {
2
+ "name": "@farmzone/fz-template-react",
3
+ "version": "1.0.8",
4
+ "description": "Farmzone React 프로젝트 보일러플레이트 생성 CLI",
5
+ "type": "module",
6
+ "bin": {
7
+ "fz-template-react": "./bin/create.js"
8
+ },
9
+ "files": [
10
+ "bin",
11
+ "template"
12
+ ],
13
+ "keywords": [
14
+ "farmzone",
15
+ "react",
16
+ "template",
17
+ "boilerplate",
18
+ "vite"
19
+ ],
20
+ "license": "UNLICENSED",
21
+ "engines": {
22
+ "node": ">=18"
23
+ }
24
+ }
@@ -1,5 +1,5 @@
1
- # API 서버 호스트 (예: http://localhost:8080)
2
- VITE_APP_API_HOST=http://localhost:8080
3
-
4
- # API 버전 (예: v1)
5
- VITE_APP_API_VERSION=v1
1
+ # API 서버 호스트 (예: http://localhost:8080)
2
+ VITE_APP_API_HOST=http://localhost:8080
3
+
4
+ # API 버전 (예: v1)
5
+ VITE_APP_API_VERSION=v1
@@ -1,9 +1,9 @@
1
- {
2
- "printWidth": 110,
3
- "tabWidth": 2,
4
- "semi": true,
5
- "bracketSpacing": true,
6
- "singleQuote": false,
7
- "jsxSingleQuote": false,
8
- "trailingComma": "all"
9
- }
1
+ {
2
+ "printWidth": 110,
3
+ "tabWidth": 2,
4
+ "semi": true,
5
+ "bracketSpacing": true,
6
+ "singleQuote": false,
7
+ "jsxSingleQuote": false,
8
+ "trailingComma": "all"
9
+ }
@@ -1,26 +1,26 @@
1
- import js from "@eslint/js";
2
- import globals from "globals";
3
- import reactHooks from "eslint-plugin-react-hooks";
4
- import reactRefresh from "eslint-plugin-react-refresh";
5
- import tseslint from "typescript-eslint";
6
- import { defineConfig, globalIgnores } from "eslint/config";
7
-
8
- export default defineConfig([
9
- globalIgnores(["dist"]),
10
- {
11
- files: ["**/*.{ts,tsx}"],
12
- extends: [
13
- js.configs.recommended,
14
- tseslint.configs.recommended,
15
- reactHooks.configs["recommended-latest"],
16
- reactRefresh.configs.vite,
17
- ],
18
- languageOptions: {
19
- ecmaVersion: 2020,
20
- globals: globals.browser,
21
- },
22
- rules: {
23
- "@typescript-eslint/array-type": ["error", { default: "generic" }],
24
- },
25
- },
26
- ]);
1
+ import js from "@eslint/js";
2
+ import globals from "globals";
3
+ import reactHooks from "eslint-plugin-react-hooks";
4
+ import reactRefresh from "eslint-plugin-react-refresh";
5
+ import tseslint from "typescript-eslint";
6
+ import { defineConfig, globalIgnores } from "eslint/config";
7
+
8
+ export default defineConfig([
9
+ globalIgnores(["dist"]),
10
+ {
11
+ files: ["**/*.{ts,tsx}"],
12
+ extends: [
13
+ js.configs.recommended,
14
+ tseslint.configs.recommended,
15
+ reactHooks.configs["recommended-latest"],
16
+ reactRefresh.configs.vite,
17
+ ],
18
+ languageOptions: {
19
+ ecmaVersion: 2020,
20
+ globals: globals.browser,
21
+ },
22
+ rules: {
23
+ "@typescript-eslint/array-type": ["error", { default: "generic" }],
24
+ },
25
+ },
26
+ ]);
@@ -1,32 +1,32 @@
1
- @import "tailwindcss";
2
- @import "tw-animate-css";
3
- @import "@farmzone/fz-react-ui/tw.css";
4
-
5
- @custom-variant dark (&:is(.dark *));
6
-
7
- @tailwind utilities;
8
-
9
- @theme inline {
10
- --color-main: #3b82f6;
11
- --color-sub-lightgray: #f3f4f6;
12
- --color-sub-darkgray: #6b7280;
13
- --color-sub-darkgray-2: #374151;
14
- --color-basic-gray: #9ca3af;
15
- --color-th: rgb(250 250 250);
16
- }
17
-
18
- @layer utilities {
19
- .bg-th {
20
- background-color: var(--color-th);
21
- }
22
- }
23
-
24
- body {
25
- font-family:
26
- "Pretendard Variable",
27
- Pretendard,
28
- -apple-system,
29
- BlinkMacSystemFont,
30
- system-ui,
31
- sans-serif;
32
- }
1
+ @import "tailwindcss";
2
+ @import "tw-animate-css";
3
+ @import "@farmzone/fz-react-ui/tw.css";
4
+
5
+ @custom-variant dark (&:is(.dark *));
6
+
7
+ @tailwind utilities;
8
+
9
+ @theme inline {
10
+ --color-main: #3b82f6;
11
+ --color-sub-lightgray: #f3f4f6;
12
+ --color-sub-darkgray: #6b7280;
13
+ --color-sub-darkgray-2: #374151;
14
+ --color-basic-gray: #9ca3af;
15
+ --color-th: rgb(250 250 250);
16
+ }
17
+
18
+ @layer utilities {
19
+ .bg-th {
20
+ background-color: var(--color-th);
21
+ }
22
+ }
23
+
24
+ body {
25
+ font-family:
26
+ "Pretendard Variable",
27
+ Pretendard,
28
+ -apple-system,
29
+ BlinkMacSystemFont,
30
+ system-ui,
31
+ sans-serif;
32
+ }
@@ -1,19 +1,19 @@
1
- <!doctype html>
2
- <html lang="ko">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <link rel="icon" type="image/svg+xml" href="/favicon.ico" />
6
- <link
7
- rel="stylesheet"
8
- as="style"
9
- crossorigin
10
- href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard-dynamic-subset.min.css"
11
- />
12
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
13
- <title>fz-template-react</title>
14
- </head>
15
- <body>
16
- <div id="root"></div>
17
- <script type="module" src="/src/index.tsx"></script>
18
- </body>
19
- </html>
1
+ <!doctype html>
2
+ <html lang="ko">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/favicon.ico" />
6
+ <link
7
+ rel="stylesheet"
8
+ as="style"
9
+ crossorigin
10
+ href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard-dynamic-subset.min.css"
11
+ />
12
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
13
+ <title>fz-template-react</title>
14
+ </head>
15
+ <body>
16
+ <div id="root"></div>
17
+ <script type="module" src="/src/index.tsx"></script>
18
+ </body>
19
+ </html>