@farmzone/fz-template-react 1.0.2 → 1.0.4

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 (51) hide show
  1. package/package.json +1 -1
  2. package/template/.env.example +5 -5
  3. package/template/package.json +55 -55
  4. package/template/pnpm-lock.yaml +4214 -0
  5. package/template/public/mockServiceWorker.js +349 -349
  6. package/template/src/app/api/api.ts +178 -178
  7. package/template/src/app/api/queries.ts +321 -321
  8. package/template/src/app/api/queryKey.ts +7 -7
  9. package/template/src/app/api/token.ts +7 -7
  10. package/template/src/app/layout/Layout.tsx +33 -33
  11. package/template/src/app/layout/ListContents.tsx +9 -9
  12. package/template/src/app/layout/ListHeader.tsx +41 -41
  13. package/template/src/app/layout/MultiTabNav.tsx +101 -101
  14. package/template/src/app/layout/Sidebar.tsx +33 -33
  15. package/template/src/app/layout/UserInfo.tsx +94 -94
  16. package/template/src/app/layout/menu.ts +4 -1
  17. package/template/src/app/layout/tabSwitchStore.ts +11 -11
  18. package/template/src/app/router/Router.tsx +56 -54
  19. package/template/src/app/store/index.ts +26 -26
  20. package/template/src/index.tsx +21 -21
  21. package/template/src/mocks/browser.ts +17 -17
  22. package/template/src/mocks/handlers.ts +43 -43
  23. package/template/src/mocks/scenarios.ts +57 -57
  24. package/template/src/pages/dashboard/index.tsx +541 -541
  25. package/template/src/pages/error/Error.tsx +29 -29
  26. package/template/src/pages/error/NotFound.tsx +27 -27
  27. package/template/src/pages/login/index.tsx +317 -317
  28. package/template/src/pages/post/PostFormModal.tsx +128 -128
  29. package/template/src/pages/post/detail/index.tsx +548 -548
  30. package/template/src/pages/post/index.tsx +267 -267
  31. package/template/src/pages/sample/SampleFormModal.tsx +77 -77
  32. package/template/src/pages/sample/detail/index.tsx +424 -424
  33. package/template/src/pages/sample/index.tsx +269 -269
  34. package/template/src/pages/sample/modal/index.tsx +253 -0
  35. package/template/src/pages/system/log/index.tsx +173 -173
  36. package/template/src/pages/user/config/columns.tsx +109 -109
  37. package/template/src/pages/user/config/schema.ts +54 -54
  38. package/template/src/pages/user/index.tsx +641 -641
  39. package/template/src/shared/components/CommentInput.tsx +243 -243
  40. package/template/src/shared/config/text.ts +27 -27
  41. package/template/src/shared/utils/format.ts +11 -11
  42. package/template/src/types/auth.ts +10 -10
  43. package/template/src/types/comment.ts +33 -33
  44. package/template/src/types/common.ts +19 -19
  45. package/template/src/types/dashboard.ts +53 -53
  46. package/template/src/types/index.ts +16 -16
  47. package/template/src/types/log.ts +21 -21
  48. package/template/src/types/post.ts +32 -32
  49. package/template/src/types/sample.ts +28 -28
  50. package/template/src/types/user.ts +51 -51
  51. package/template/src/vite-env.d.ts +10 -10
@@ -1,109 +1,109 @@
1
- import { Badge, Button, type Column } from "@farmzone/fz-react-ui";
2
- import { Pencil, Trash2 } from "lucide-react";
3
-
4
- import type { User } from "@/types";
5
- import { formatDateTime } from "@/shared/utils/format";
6
-
7
- const ROLE_LABEL: Record<string, string> = {
8
- ADMIN: "관리자",
9
- USER: "일반",
10
- };
11
-
12
- interface ActionHandlers {
13
- onEdit: (user: User) => void;
14
- onDelete: (user: User) => void;
15
- totalElements: number;
16
- page: number;
17
- pageSize: number;
18
- }
19
-
20
- export const getUserColumns = ({
21
- onEdit,
22
- onDelete,
23
- totalElements,
24
- page,
25
- pageSize,
26
- }: ActionHandlers): Array<Column<User>> => [
27
- {
28
- key: "index",
29
- title: "No",
30
- width: "30px",
31
- align: "center",
32
- render: (_, __, index) => totalElements - page * pageSize - index,
33
- },
34
- { key: "userId", title: "아이디", minWidth: 100 },
35
- { key: "name", title: "이름", minWidth: 80 },
36
- {
37
- key: "role",
38
- title: "권한",
39
- align: "center",
40
- width: "40px",
41
- render: (_, record) => ROLE_LABEL[record.role] ?? record.role,
42
- },
43
- {
44
- key: "active",
45
- title: "사용여부",
46
- align: "center",
47
- width: "50px",
48
- render: (_, record) => (
49
- <Badge
50
- text={record.active ? "O" : "X"}
51
- className={`scale-90 ${
52
- record.active
53
- ? "bg-green-100 text-green-700 border-green-100"
54
- : "bg-red-100 text-red-500 border-red-100"
55
- }`}
56
- />
57
- ),
58
- },
59
- {
60
- key: "createdAt",
61
- title: "등록일시",
62
- align: "center",
63
- width: "80px",
64
- render: (_, record) => formatDateTime(record.createdAt),
65
- },
66
- {
67
- key: "lastLoginAt",
68
- title: "최종 로그인",
69
- align: "center",
70
- width: "80px",
71
- render: (_, record) => formatDateTime(record.lastLoginAt),
72
- },
73
- // {
74
- // key: "actions",
75
- // title: "관리",
76
- // align: "center",
77
- // width: "40px",
78
- // render: (_, record) => (
79
- // <div className="flex items-center justify-center gap-1">
80
- // <Button
81
- // type="button"
82
- // variant="ghost"
83
- // size="icon-sm"
84
- // className="cursor-pointer rounded p-1 text-gray-400 hover:bg-gray-100 hover:text-blue-500"
85
- // onClick={(e) => {
86
- // e.stopPropagation();
87
- // onEdit(record);
88
- // }}
89
- // aria-label="수정"
90
- // >
91
- // <Pencil size={15} />
92
- // </Button>
93
- // <Button
94
- // type="button"
95
- // variant="ghost"
96
- // size="icon-sm"
97
- // className="cursor-pointer rounded p-1 text-gray-400 hover:bg-gray-100 hover:text-red-500"
98
- // onClick={(e) => {
99
- // e.stopPropagation();
100
- // onDelete(record);
101
- // }}
102
- // aria-label="삭제"
103
- // >
104
- // <Trash2 size={15} />
105
- // </Button>
106
- // </div>
107
- // ),
108
- // },
109
- ];
1
+ import { Badge, Button, type Column } from "@farmzone/fz-react-ui";
2
+ import { Pencil, Trash2 } from "lucide-react";
3
+
4
+ import type { User } from "@/types";
5
+ import { formatDateTime } from "@/shared/utils/format";
6
+
7
+ const ROLE_LABEL: Record<string, string> = {
8
+ ADMIN: "관리자",
9
+ USER: "일반",
10
+ };
11
+
12
+ interface ActionHandlers {
13
+ onEdit: (user: User) => void;
14
+ onDelete: (user: User) => void;
15
+ totalElements: number;
16
+ page: number;
17
+ pageSize: number;
18
+ }
19
+
20
+ export const getUserColumns = ({
21
+ onEdit,
22
+ onDelete,
23
+ totalElements,
24
+ page,
25
+ pageSize,
26
+ }: ActionHandlers): Array<Column<User>> => [
27
+ {
28
+ key: "index",
29
+ title: "No",
30
+ width: "30px",
31
+ align: "center",
32
+ render: (_, __, index) => totalElements - page * pageSize - index,
33
+ },
34
+ { key: "userId", title: "아이디", minWidth: 100 },
35
+ { key: "name", title: "이름", minWidth: 80 },
36
+ {
37
+ key: "role",
38
+ title: "권한",
39
+ align: "center",
40
+ width: "40px",
41
+ render: (_, record) => ROLE_LABEL[record.role] ?? record.role,
42
+ },
43
+ {
44
+ key: "active",
45
+ title: "사용여부",
46
+ align: "center",
47
+ width: "50px",
48
+ render: (_, record) => (
49
+ <Badge
50
+ text={record.active ? "O" : "X"}
51
+ className={`scale-90 ${
52
+ record.active
53
+ ? "bg-green-100 text-green-700 border-green-100"
54
+ : "bg-red-100 text-red-500 border-red-100"
55
+ }`}
56
+ />
57
+ ),
58
+ },
59
+ {
60
+ key: "createdAt",
61
+ title: "등록일시",
62
+ align: "center",
63
+ width: "80px",
64
+ render: (_, record) => formatDateTime(record.createdAt),
65
+ },
66
+ {
67
+ key: "lastLoginAt",
68
+ title: "최종 로그인",
69
+ align: "center",
70
+ width: "80px",
71
+ render: (_, record) => formatDateTime(record.lastLoginAt),
72
+ },
73
+ // {
74
+ // key: "actions",
75
+ // title: "관리",
76
+ // align: "center",
77
+ // width: "40px",
78
+ // render: (_, record) => (
79
+ // <div className="flex items-center justify-center gap-1">
80
+ // <Button
81
+ // type="button"
82
+ // variant="ghost"
83
+ // size="icon-sm"
84
+ // className="cursor-pointer rounded p-1 text-gray-400 hover:bg-gray-100 hover:text-blue-500"
85
+ // onClick={(e) => {
86
+ // e.stopPropagation();
87
+ // onEdit(record);
88
+ // }}
89
+ // aria-label="수정"
90
+ // >
91
+ // <Pencil size={15} />
92
+ // </Button>
93
+ // <Button
94
+ // type="button"
95
+ // variant="ghost"
96
+ // size="icon-sm"
97
+ // className="cursor-pointer rounded p-1 text-gray-400 hover:bg-gray-100 hover:text-red-500"
98
+ // onClick={(e) => {
99
+ // e.stopPropagation();
100
+ // onDelete(record);
101
+ // }}
102
+ // aria-label="삭제"
103
+ // >
104
+ // <Trash2 size={15} />
105
+ // </Button>
106
+ // </div>
107
+ // ),
108
+ // },
109
+ ];
@@ -1,54 +1,54 @@
1
- import { z } from "zod";
2
-
3
- export const userCreateSchema = z
4
- .object({
5
- userId: z.string().min(1, "아이디를 입력해 주세요."),
6
- name: z.string().min(1, "성명을 입력해 주세요."),
7
- password: z.string().min(1, "비밀번호를 입력해 주세요."),
8
- passwordCheck: z.string().min(1, "비밀번호 확인을 입력해 주세요."),
9
- role: z.string(),
10
- gender: z.enum(["M", "F", ""]).default(""),
11
- birthday: z.string().default(""),
12
- phone: z
13
- .string()
14
- .regex(/^[0-9\-]{0,20}$/, "숫자와 하이픈(-)만 입력 가능합니다.")
15
- .default(""),
16
- })
17
- .superRefine((data, ctx) => {
18
- if (data.password !== data.passwordCheck) {
19
- ctx.addIssue({
20
- code: z.ZodIssueCode.custom,
21
- message: "비밀번호가 일치하지 않습니다.",
22
- path: ["passwordCheck"],
23
- });
24
- }
25
- });
26
-
27
- export type UserCreateFormData = z.infer<typeof userCreateSchema>;
28
-
29
- export const userEditSchema = z
30
- .object({
31
- userId: z.string().default(""),
32
- name: z.string().min(1, "성명을 입력해 주세요."),
33
- password: z.string().default(""),
34
- passwordCheck: z.string().default(""),
35
- active: z.boolean().default(true),
36
- role: z.string(),
37
- gender: z.enum(["M", "F", ""]).default(""),
38
- birthday: z.string().default(""),
39
- phone: z
40
- .string()
41
- .regex(/^[0-9\-]{0,20}$/, "숫자와 하이픈(-)만 입력 가능합니다.")
42
- .default(""),
43
- })
44
- .superRefine((data, ctx) => {
45
- if (data.password && data.password !== data.passwordCheck) {
46
- ctx.addIssue({
47
- code: z.ZodIssueCode.custom,
48
- message: "비밀번호가 일치하지 않습니다.",
49
- path: ["passwordCheck"],
50
- });
51
- }
52
- });
53
-
54
- export type UserEditFormData = z.infer<typeof userEditSchema>;
1
+ import { z } from "zod";
2
+
3
+ export const userCreateSchema = z
4
+ .object({
5
+ userId: z.string().min(1, "아이디를 입력해 주세요."),
6
+ name: z.string().min(1, "성명을 입력해 주세요."),
7
+ password: z.string().min(1, "비밀번호를 입력해 주세요."),
8
+ passwordCheck: z.string().min(1, "비밀번호 확인을 입력해 주세요."),
9
+ role: z.string(),
10
+ gender: z.enum(["M", "F", ""]).default(""),
11
+ birthday: z.string().default(""),
12
+ phone: z
13
+ .string()
14
+ .regex(/^[0-9\-]{0,20}$/, "숫자와 하이픈(-)만 입력 가능합니다.")
15
+ .default(""),
16
+ })
17
+ .superRefine((data, ctx) => {
18
+ if (data.password !== data.passwordCheck) {
19
+ ctx.addIssue({
20
+ code: z.ZodIssueCode.custom,
21
+ message: "비밀번호가 일치하지 않습니다.",
22
+ path: ["passwordCheck"],
23
+ });
24
+ }
25
+ });
26
+
27
+ export type UserCreateFormData = z.infer<typeof userCreateSchema>;
28
+
29
+ export const userEditSchema = z
30
+ .object({
31
+ userId: z.string().default(""),
32
+ name: z.string().min(1, "성명을 입력해 주세요."),
33
+ password: z.string().default(""),
34
+ passwordCheck: z.string().default(""),
35
+ active: z.boolean().default(true),
36
+ role: z.string(),
37
+ gender: z.enum(["M", "F", ""]).default(""),
38
+ birthday: z.string().default(""),
39
+ phone: z
40
+ .string()
41
+ .regex(/^[0-9\-]{0,20}$/, "숫자와 하이픈(-)만 입력 가능합니다.")
42
+ .default(""),
43
+ })
44
+ .superRefine((data, ctx) => {
45
+ if (data.password && data.password !== data.passwordCheck) {
46
+ ctx.addIssue({
47
+ code: z.ZodIssueCode.custom,
48
+ message: "비밀번호가 일치하지 않습니다.",
49
+ path: ["passwordCheck"],
50
+ });
51
+ }
52
+ });
53
+
54
+ export type UserEditFormData = z.infer<typeof userEditSchema>;