zenstack 1.0.0 → 1.0.16

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 (264) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +126 -1
  3. package/bin/cli +3 -0
  4. package/bin/post-install.js +24 -0
  5. package/cli/cli-error.d.ts +5 -0
  6. package/cli/cli-error.js +10 -0
  7. package/cli/cli-error.js.map +1 -0
  8. package/cli/cli-util.d.ts +18 -0
  9. package/cli/cli-util.js +143 -0
  10. package/cli/cli-util.js.map +1 -0
  11. package/cli/index.d.ts +15 -0
  12. package/cli/index.js +121 -0
  13. package/cli/index.js.map +1 -0
  14. package/cli/plugin-runner.d.ts +14 -0
  15. package/cli/plugin-runner.js +145 -0
  16. package/cli/plugin-runner.js.map +1 -0
  17. package/constants.d.ts +1 -0
  18. package/constants.js +6 -0
  19. package/constants.js.map +1 -0
  20. package/language-server/constants.d.ts +15 -0
  21. package/language-server/constants.js +20 -0
  22. package/language-server/constants.js.map +1 -0
  23. package/language-server/main.d.ts +1 -0
  24. package/language-server/main.js +13 -0
  25. package/language-server/main.js.map +1 -0
  26. package/language-server/types.d.ts +10 -0
  27. package/language-server/types.js +3 -0
  28. package/language-server/types.js.map +1 -0
  29. package/language-server/utils.d.ts +18 -0
  30. package/language-server/utils.js +58 -0
  31. package/language-server/utils.js.map +1 -0
  32. package/language-server/validator/attribute-validator.d.ts +9 -0
  33. package/language-server/validator/attribute-validator.js +11 -0
  34. package/language-server/validator/attribute-validator.js.map +1 -0
  35. package/language-server/validator/datamodel-validator.d.ts +15 -0
  36. package/language-server/validator/datamodel-validator.js +278 -0
  37. package/language-server/validator/datamodel-validator.js.map +1 -0
  38. package/language-server/validator/datasource-validator.d.ts +12 -0
  39. package/language-server/validator/datasource-validator.js +66 -0
  40. package/language-server/validator/datasource-validator.js.map +1 -0
  41. package/language-server/validator/enum-validator.d.ts +11 -0
  42. package/language-server/validator/enum-validator.js +28 -0
  43. package/language-server/validator/enum-validator.js.map +1 -0
  44. package/language-server/validator/expression-validator.d.ts +10 -0
  45. package/language-server/validator/expression-validator.js +30 -0
  46. package/language-server/validator/expression-validator.js.map +1 -0
  47. package/language-server/validator/schema-validator.d.ts +10 -0
  48. package/language-server/validator/schema-validator.js +28 -0
  49. package/language-server/validator/schema-validator.js.map +1 -0
  50. package/language-server/validator/utils.d.ts +25 -0
  51. package/language-server/validator/utils.js +257 -0
  52. package/language-server/validator/utils.js.map +1 -0
  53. package/language-server/validator/zmodel-validator.d.ts +21 -0
  54. package/language-server/validator/zmodel-validator.js +69 -0
  55. package/language-server/validator/zmodel-validator.js.map +1 -0
  56. package/language-server/zmodel-code-action.d.ts +14 -0
  57. package/language-server/zmodel-code-action.js +93 -0
  58. package/language-server/zmodel-code-action.js.map +1 -0
  59. package/language-server/zmodel-formatter.d.ts +9 -0
  60. package/language-server/zmodel-formatter.js +76 -0
  61. package/language-server/zmodel-formatter.js.map +1 -0
  62. package/language-server/zmodel-linker.d.ts +29 -0
  63. package/language-server/zmodel-linker.js +366 -0
  64. package/language-server/zmodel-linker.js.map +1 -0
  65. package/language-server/zmodel-module.d.ts +41 -0
  66. package/language-server/zmodel-module.js +80 -0
  67. package/language-server/zmodel-module.js.map +1 -0
  68. package/language-server/zmodel-scope.d.ts +10 -0
  69. package/language-server/zmodel-scope.js +44 -0
  70. package/language-server/zmodel-scope.js.map +1 -0
  71. package/language-server/zmodel-workspace-manager.d.ts +8 -0
  72. package/language-server/zmodel-workspace-manager.js +37 -0
  73. package/language-server/zmodel-workspace-manager.js.map +1 -0
  74. package/package.json +133 -8
  75. package/plugins/access-policy/expression-writer.d.ts +39 -0
  76. package/plugins/access-policy/expression-writer.js +361 -0
  77. package/plugins/access-policy/expression-writer.js.map +1 -0
  78. package/plugins/access-policy/index.d.ts +4 -0
  79. package/plugins/access-policy/index.js +24 -0
  80. package/plugins/access-policy/index.js.map +1 -0
  81. package/plugins/access-policy/policy-guard-generator.d.ts +15 -0
  82. package/plugins/access-policy/policy-guard-generator.js +349 -0
  83. package/plugins/access-policy/policy-guard-generator.js.map +1 -0
  84. package/plugins/access-policy/typescript-expression-transformer.d.ts +26 -0
  85. package/plugins/access-policy/typescript-expression-transformer.js +111 -0
  86. package/plugins/access-policy/typescript-expression-transformer.js.map +1 -0
  87. package/plugins/access-policy/utils.d.ts +5 -0
  88. package/plugins/access-policy/utils.js +14 -0
  89. package/plugins/access-policy/utils.js.map +1 -0
  90. package/plugins/access-policy/zod-schema-generator.d.ts +12 -0
  91. package/plugins/access-policy/zod-schema-generator.js +158 -0
  92. package/plugins/access-policy/zod-schema-generator.js.map +1 -0
  93. package/plugins/model-meta/index.d.ts +4 -0
  94. package/plugins/model-meta/index.js +168 -0
  95. package/plugins/model-meta/index.js.map +1 -0
  96. package/plugins/plugin-utils.d.ts +16 -0
  97. package/plugins/plugin-utils.js +54 -0
  98. package/plugins/plugin-utils.js.map +1 -0
  99. package/plugins/prisma/indent-string.d.ts +4 -0
  100. package/plugins/prisma/indent-string.js +12 -0
  101. package/plugins/prisma/indent-string.js.map +1 -0
  102. package/plugins/prisma/index.d.ts +4 -0
  103. package/plugins/prisma/index.js +24 -0
  104. package/plugins/prisma/index.js.map +1 -0
  105. package/plugins/prisma/prisma-builder.d.ts +152 -0
  106. package/plugins/prisma/prisma-builder.js +363 -0
  107. package/plugins/prisma/prisma-builder.js.map +1 -0
  108. package/plugins/prisma/schema-generator.d.ts +25 -0
  109. package/plugins/prisma/schema-generator.js +292 -0
  110. package/plugins/prisma/schema-generator.js.map +1 -0
  111. package/plugins/prisma/zmodel-code-generator.d.ts +28 -0
  112. package/plugins/prisma/zmodel-code-generator.js +114 -0
  113. package/plugins/prisma/zmodel-code-generator.js.map +1 -0
  114. package/res/prism-zmodel.js +20 -0
  115. package/res/starter.zmodel +51 -0
  116. package/res/stdlib.zmodel +346 -0
  117. package/telemetry.d.ts +20 -0
  118. package/telemetry.js +119 -0
  119. package/telemetry.js.map +1 -0
  120. package/types.d.ts +12 -0
  121. package/types.js +3 -0
  122. package/types.js.map +1 -0
  123. package/utils/ast-utils.d.ts +16 -0
  124. package/utils/ast-utils.js +85 -0
  125. package/utils/ast-utils.js.map +1 -0
  126. package/utils/exec-utils.d.ts +6 -0
  127. package/utils/exec-utils.js +13 -0
  128. package/utils/exec-utils.js.map +1 -0
  129. package/utils/pkg-utils.d.ts +3 -0
  130. package/utils/pkg-utils.js +46 -0
  131. package/utils/pkg-utils.js.map +1 -0
  132. package/utils/version-utils.d.ts +1 -0
  133. package/utils/version-utils.js +14 -0
  134. package/utils/version-utils.js.map +1 -0
  135. package/.vscode/extensions.json +0 -7
  136. package/.vscode/launch.json +0 -49
  137. package/.vscode/settings.json +0 -4
  138. package/packages/internal/jest.config.ts +0 -32
  139. package/packages/internal/package.json +0 -42
  140. package/packages/internal/src/constants.ts +0 -1
  141. package/packages/internal/src/handler/data/guard-utils.ts +0 -7
  142. package/packages/internal/src/handler/data/handler.ts +0 -415
  143. package/packages/internal/src/handler/data/query-processor.ts +0 -504
  144. package/packages/internal/src/handler/index.ts +0 -1
  145. package/packages/internal/src/handler/types.ts +0 -20
  146. package/packages/internal/src/index.ts +0 -3
  147. package/packages/internal/src/request-handler.ts +0 -27
  148. package/packages/internal/src/request.ts +0 -101
  149. package/packages/internal/src/types.ts +0 -40
  150. package/packages/internal/tests/query-processor.test.ts +0 -172
  151. package/packages/internal/tsconfig.json +0 -21
  152. package/packages/runtime/auth.d.ts +0 -1
  153. package/packages/runtime/auth.js +0 -3
  154. package/packages/runtime/hooks.d.ts +0 -10
  155. package/packages/runtime/hooks.js +0 -3
  156. package/packages/runtime/index.d.ts +0 -3
  157. package/packages/runtime/index.js +0 -1
  158. package/packages/runtime/package-lock.json +0 -512
  159. package/packages/runtime/package.json +0 -16
  160. package/packages/runtime/server.d.ts +0 -1
  161. package/packages/runtime/server.js +0 -3
  162. package/packages/runtime/types.d.ts +0 -1
  163. package/packages/runtime/types.js +0 -3
  164. package/packages/schema/.eslintrc.json +0 -13
  165. package/packages/schema/.vscodeignore +0 -4
  166. package/packages/schema/asset/logo-dark.png +0 -0
  167. package/packages/schema/asset/logo-light.png +0 -0
  168. package/packages/schema/bin/cli +0 -3
  169. package/packages/schema/jest.config.ts +0 -32
  170. package/packages/schema/langium-config.json +0 -14
  171. package/packages/schema/langium-quickstart.md +0 -41
  172. package/packages/schema/language-configuration.json +0 -30
  173. package/packages/schema/package.json +0 -96
  174. package/packages/schema/src/cli/cli-util.ts +0 -80
  175. package/packages/schema/src/cli/index.ts +0 -64
  176. package/packages/schema/src/extension.ts +0 -76
  177. package/packages/schema/src/generator/constants.ts +0 -5
  178. package/packages/schema/src/generator/index.ts +0 -92
  179. package/packages/schema/src/generator/next-auth/index.ts +0 -197
  180. package/packages/schema/src/generator/package.template.json +0 -9
  181. package/packages/schema/src/generator/prisma/expression-writer.ts +0 -352
  182. package/packages/schema/src/generator/prisma/index.ts +0 -32
  183. package/packages/schema/src/generator/prisma/plain-expression-builder.ts +0 -91
  184. package/packages/schema/src/generator/prisma/prisma-builder.ts +0 -366
  185. package/packages/schema/src/generator/prisma/query-gard-generator.ts +0 -208
  186. package/packages/schema/src/generator/prisma/schema-generator.ts +0 -300
  187. package/packages/schema/src/generator/react-hooks/index.ts +0 -181
  188. package/packages/schema/src/generator/service/index.ts +0 -107
  189. package/packages/schema/src/generator/tsconfig.template.json +0 -17
  190. package/packages/schema/src/generator/types.ts +0 -17
  191. package/packages/schema/src/generator/utils.ts +0 -9
  192. package/packages/schema/src/language-server/generated/ast.ts +0 -603
  193. package/packages/schema/src/language-server/generated/grammar.ts +0 -2190
  194. package/packages/schema/src/language-server/generated/module.ts +0 -24
  195. package/packages/schema/src/language-server/main.ts +0 -12
  196. package/packages/schema/src/language-server/stdlib.zmodel +0 -22
  197. package/packages/schema/src/language-server/types.ts +0 -9
  198. package/packages/schema/src/language-server/zmodel-index.ts +0 -33
  199. package/packages/schema/src/language-server/zmodel-linker.ts +0 -409
  200. package/packages/schema/src/language-server/zmodel-module.ts +0 -90
  201. package/packages/schema/src/language-server/zmodel-scope.ts +0 -21
  202. package/packages/schema/src/language-server/zmodel-validator.ts +0 -35
  203. package/packages/schema/src/language-server/zmodel.langium +0 -186
  204. package/packages/schema/src/utils/exec-utils.ts +0 -5
  205. package/packages/schema/src/utils/indent-string.ts +0 -6
  206. package/packages/schema/syntaxes/zmodel.json +0 -57
  207. package/packages/schema/syntaxes/zmodel.tmLanguage.json +0 -57
  208. package/packages/schema/tests/generator/expression-writer.test.ts +0 -676
  209. package/packages/schema/tests/generator/prisma-builder.test.ts +0 -138
  210. package/packages/schema/tests/schema/parser.test.ts +0 -423
  211. package/packages/schema/tests/schema/sample-todo.test.ts +0 -14
  212. package/packages/schema/tests/utils.ts +0 -38
  213. package/packages/schema/tsconfig.json +0 -23
  214. package/pnpm-workspace.yaml +0 -3
  215. package/samples/todo/.env +0 -2
  216. package/samples/todo/.eslintrc.json +0 -3
  217. package/samples/todo/.vscode/launch.json +0 -11
  218. package/samples/todo/README.md +0 -34
  219. package/samples/todo/components/AuthGuard.tsx +0 -17
  220. package/samples/todo/components/Avatar.tsx +0 -22
  221. package/samples/todo/components/BreadCrumb.tsx +0 -44
  222. package/samples/todo/components/ManageMembers.tsx +0 -134
  223. package/samples/todo/components/NavBar.tsx +0 -57
  224. package/samples/todo/components/SpaceMembers.tsx +0 -76
  225. package/samples/todo/components/Spaces.tsx +0 -28
  226. package/samples/todo/components/TimeInfo.tsx +0 -17
  227. package/samples/todo/components/Todo.tsx +0 -72
  228. package/samples/todo/components/TodoList.tsx +0 -77
  229. package/samples/todo/lib/context.ts +0 -31
  230. package/samples/todo/next.config.js +0 -10
  231. package/samples/todo/package-lock.json +0 -7527
  232. package/samples/todo/package.json +0 -45
  233. package/samples/todo/pages/_app.tsx +0 -50
  234. package/samples/todo/pages/api/auth/[...nextauth].ts +0 -83
  235. package/samples/todo/pages/api/zenstack/[...path].ts +0 -16
  236. package/samples/todo/pages/create-space.tsx +0 -114
  237. package/samples/todo/pages/index.tsx +0 -32
  238. package/samples/todo/pages/space/[slug]/[listId]/index.tsx +0 -88
  239. package/samples/todo/pages/space/[slug]/index.tsx +0 -169
  240. package/samples/todo/postcss.config.js +0 -6
  241. package/samples/todo/public/avatar.jpg +0 -0
  242. package/samples/todo/public/favicon.ico +0 -0
  243. package/samples/todo/public/logo.png +0 -0
  244. package/samples/todo/public/vercel.svg +0 -4
  245. package/samples/todo/styles/globals.css +0 -7
  246. package/samples/todo/tailwind.config.js +0 -11
  247. package/samples/todo/tsconfig.json +0 -28
  248. package/samples/todo/types/next-auth.d.ts +0 -14
  249. package/samples/todo/types/next.d.ts +0 -16
  250. package/samples/todo/zenstack/migrations/20221014084317_init/migration.sql +0 -153
  251. package/samples/todo/zenstack/migrations/20221020094651_upate_cli/migration.sql +0 -23
  252. package/samples/todo/zenstack/migrations/migration_lock.toml +0 -3
  253. package/samples/todo/zenstack/schema.prisma +0 -126
  254. package/samples/todo/zenstack/schema.zmodel +0 -161
  255. package/tests/integration/jest.config.ts +0 -16
  256. package/tests/integration/package-lock.json +0 -1081
  257. package/tests/integration/package.json +0 -27
  258. package/tests/integration/tests/operation-coverate.test.ts +0 -563
  259. package/tests/integration/tests/operations.zmodel +0 -69
  260. package/tests/integration/tests/todo-e2e.test.ts +0 -577
  261. package/tests/integration/tests/todo.zmodel +0 -123
  262. package/tests/integration/tests/tsconfig.template.json +0 -10
  263. package/tests/integration/tests/utils.ts +0 -133
  264. package/tests/integration/tsconfig.json +0 -10
@@ -1,17 +0,0 @@
1
- import { signIn, useSession } from 'next-auth/react';
2
-
3
- type Props = {
4
- children: JSX.Element | JSX.Element[];
5
- };
6
-
7
- export default function AuthGuard({ children }: Props) {
8
- const { status } = useSession();
9
- if (status === 'loading') {
10
- return <p>Loading...</p>;
11
- } else if (status === 'unauthenticated') {
12
- signIn();
13
- return <></>;
14
- } else {
15
- return <>{children}</>;
16
- }
17
- }
@@ -1,22 +0,0 @@
1
- import { UserIcon } from '@heroicons/react/24/outline';
2
- import { User } from 'next-auth';
3
- import Image from 'next/image';
4
-
5
- type Props = {
6
- user: User;
7
- size?: number;
8
- };
9
-
10
- export default function Avatar({ user, size }: Props) {
11
- return (
12
- <div className="tooltip" data-tip={user.name || user.email}>
13
- <Image
14
- src={user.image || '/avatar.jpg'}
15
- alt="avatar"
16
- width={size || 32}
17
- height={size || 32}
18
- className="rounded-full"
19
- />
20
- </div>
21
- );
22
- }
@@ -1,44 +0,0 @@
1
- import { useList } from '@zenstackhq/runtime/hooks';
2
- import Link from 'next/link';
3
- import { useRouter } from 'next/router';
4
- import { useCurrentSpace } from '@lib/context';
5
-
6
- export default function BreadCrumb() {
7
- const router = useRouter();
8
- const space = useCurrentSpace();
9
- const { get: getList } = useList();
10
-
11
- const parts = router.asPath.split('/').filter((p) => p);
12
-
13
- const [base, slug, listId] = parts;
14
- if (base !== 'space') {
15
- return <></>;
16
- }
17
-
18
- const items: Array<{ text: string; link: string }> = [];
19
-
20
- items.push({ text: 'Home', link: '/' });
21
- items.push({ text: space?.name || '', link: `/space/${slug}` });
22
-
23
- if (listId) {
24
- const { data } = getList(listId);
25
- items.push({
26
- text: data?.title || '',
27
- link: `/space/${slug}/${listId}`,
28
- });
29
- }
30
-
31
- return (
32
- <div className="text-sm text-gray-600 breadcrumbs">
33
- <ul>
34
- {items.map((item, i) => (
35
- <li key={i}>
36
- <Link href={item.link}>
37
- <a>{item.text}</a>
38
- </Link>
39
- </li>
40
- ))}
41
- </ul>
42
- </div>
43
- );
44
- }
@@ -1,134 +0,0 @@
1
- import { PlusIcon, TrashIcon } from '@heroicons/react/24/outline';
2
- import { useCurrentUser } from '@lib/context';
3
- import { ServerErrorCode } from '@zenstackhq/internal';
4
- import { HooksError, useSpaceUser } from '@zenstackhq/runtime/hooks';
5
- import { Space, SpaceUserRole } from '@zenstackhq/runtime/types';
6
- import { ChangeEvent, KeyboardEvent, useState } from 'react';
7
- import { toast } from 'react-toastify';
8
- import Avatar from './Avatar';
9
-
10
- type Props = {
11
- space: Space;
12
- };
13
-
14
- export default function ManageMembers({ space }: Props) {
15
- const [email, setEmail] = useState('');
16
- const [role, setRole] = useState<SpaceUserRole>(SpaceUserRole.USER);
17
- const user = useCurrentUser();
18
-
19
- const { find, create: addMember, del: delMember } = useSpaceUser();
20
- const { data: members } = find({
21
- where: {
22
- spaceId: space.id,
23
- },
24
- include: {
25
- user: true,
26
- },
27
- });
28
-
29
- const inviteUser = async () => {
30
- try {
31
- const r = await addMember({
32
- data: {
33
- user: {
34
- connect: {
35
- email,
36
- },
37
- },
38
- space: {
39
- connect: {
40
- id: space.id,
41
- },
42
- },
43
- role,
44
- },
45
- });
46
- console.log('SpaceUser created:', r);
47
- } catch (err: any) {
48
- console.error(JSON.stringify(err));
49
- if (err.info?.code) {
50
- const { info } = err as HooksError;
51
- if (info.code === ServerErrorCode.UNIQUE_CONSTRAINT_VIOLATION) {
52
- toast.error('User is already a member of the space');
53
- } else if (
54
- info.code === ServerErrorCode.REFERENCE_CONSTRAINT_VIOLATION
55
- ) {
56
- toast.error('User is not found for this email');
57
- }
58
- } else {
59
- toast.error(`Error occurred: ${err}`);
60
- }
61
- }
62
- };
63
-
64
- const removeMember = async (id: string) => {
65
- if (confirm(`Are you sure to remove this member from space?`)) {
66
- await delMember(id);
67
- }
68
- };
69
-
70
- return (
71
- <div>
72
- <div className="flex flex-wrap gap-2 items-center mb-8 w-full">
73
- <input
74
- type="text"
75
- placeholder="Type user email and enter to invite"
76
- className="input input-sm input-bordered flex-grow mr-2"
77
- value={email}
78
- onChange={(e: ChangeEvent<HTMLInputElement>) => {
79
- setEmail(e.currentTarget.value);
80
- }}
81
- onKeyUp={(e: KeyboardEvent<HTMLInputElement>) => {
82
- if (e.key === 'Enter') {
83
- inviteUser();
84
- }
85
- }}
86
- />
87
-
88
- <select
89
- className="select select-sm mr-2"
90
- value={role}
91
- onChange={(e: ChangeEvent<HTMLSelectElement>) => {
92
- setRole(e.currentTarget.value as SpaceUserRole);
93
- }}
94
- >
95
- <option value={SpaceUserRole.USER}>USER</option>
96
- <option value={SpaceUserRole.ADMIN}>ADMIN</option>
97
- </select>
98
-
99
- <button>
100
- <PlusIcon className="w-6 h-6 text-gray-500" />
101
- </button>
102
- </div>
103
-
104
- <ul className="space-y-2">
105
- {members?.map((member) => (
106
- <li
107
- key={member.id}
108
- className="flex flex-wrap w-full justify-between"
109
- >
110
- <div className="flex items-center">
111
- <div className="hidden md:block mr-2">
112
- <Avatar user={member.user} size={32} />
113
- </div>
114
- <p className="w-36 md:w-48 line-clamp-1 mr-2">
115
- {member.user.name || member.user.email}
116
- </p>
117
- <p>{member.role}</p>
118
- </div>
119
- <div className="flex items-center">
120
- {user?.id !== member.user.id && (
121
- <TrashIcon
122
- className="w-4 h-4 text-gray-500"
123
- onClick={() => {
124
- removeMember(member.id);
125
- }}
126
- />
127
- )}
128
- </div>
129
- </li>
130
- ))}
131
- </ul>
132
- </div>
133
- );
134
- }
@@ -1,57 +0,0 @@
1
- import Image from 'next/image';
2
- import Avatar from './Avatar';
3
- import { signOut } from 'next-auth/react';
4
- import Link from 'next/link';
5
- import { Space } from '@zenstackhq/runtime/types';
6
- import { User } from 'next-auth';
7
-
8
- type Props = {
9
- space: Space | undefined;
10
- user: User | undefined;
11
- };
12
-
13
- export default function NavBar({ user, space }: Props) {
14
- return (
15
- <div className="navbar bg-base-100 px-8 py-2 border-b">
16
- <div className="flex-1">
17
- <Link href="/">
18
- <a className="flex items-center">
19
- <Image
20
- src="/logo.png"
21
- alt="Logo"
22
- width={32}
23
- height={32}
24
- />
25
- <div className="text-xl font-semibold ml-2 text-slate-700 hidden md:inline-block">
26
- {space?.name || 'Welcome Todo App'}
27
- </div>
28
- <p className="text-xs ml-2 text-gray-500 self-end">
29
- Powered by ZenStack
30
- </p>
31
- </a>
32
- </Link>
33
- </div>
34
- <div className="flex-none">
35
- <div className="dropdown dropdown-end">
36
- <label
37
- tabIndex={0}
38
- className="btn btn-ghost btn-circle avatar"
39
- >
40
- {user && <Avatar user={user!} />}
41
- </label>
42
- <ul
43
- tabIndex={0}
44
- className="menu menu-compact dropdown-content mt-3 p-2 shadow bg-base-100 rounded-box w-52"
45
- >
46
- <li className="border-b border-gray-200">
47
- {user && <div>{user.name || user.email}</div>}
48
- </li>
49
- <li>
50
- <a onClick={() => signOut()}>Logout</a>
51
- </li>
52
- </ul>
53
- </div>
54
- </div>
55
- </div>
56
- );
57
- }
@@ -1,76 +0,0 @@
1
- import { useSpaceUser } from '@zenstackhq/runtime/hooks';
2
- import { useCurrentSpace } from '@lib/context';
3
- import { PlusIcon } from '@heroicons/react/24/outline';
4
- import Avatar from './Avatar';
5
- import ManageMembers from './ManageMembers';
6
- import { Space } from '@zenstackhq/runtime/types';
7
-
8
- function ManagementDialog(space?: Space) {
9
- if (!space) return undefined;
10
- return (
11
- <>
12
- <label htmlFor="management-modal" className="modal-button">
13
- <PlusIcon className="w-6 h-6 text-gray-500 cursor-pointer mr-1" />
14
- </label>
15
-
16
- <input
17
- type="checkbox"
18
- id="management-modal"
19
- className="modal-toggle"
20
- />
21
- <div className="modal">
22
- <div className="modal-box">
23
- <h3 className="font-bold text-base md:text-lg">
24
- Manage Members of {space.name}
25
- </h3>
26
-
27
- <div className="p-4 mt-4">
28
- <ManageMembers space={space} />
29
- </div>
30
-
31
- <div className="modal-action">
32
- <label
33
- htmlFor="management-modal"
34
- className="btn btn-outline"
35
- >
36
- Close
37
- </label>
38
- </div>
39
- </div>
40
- </div>
41
- </>
42
- );
43
- }
44
-
45
- export default function SpaceMembers() {
46
- const space = useCurrentSpace();
47
-
48
- const { find: findMembers } = useSpaceUser();
49
- const { data: members } = findMembers({
50
- where: {
51
- spaceId: space?.id,
52
- },
53
- include: {
54
- user: true,
55
- },
56
- orderBy: {
57
- role: 'desc',
58
- },
59
- });
60
-
61
- return (
62
- <div className="flex items-center">
63
- {ManagementDialog(space)}
64
- {members && (
65
- <label
66
- className="mr-1 modal-button cursor-pointer"
67
- htmlFor="management-modal"
68
- >
69
- {members?.map((member) => (
70
- <Avatar key={member.id} user={member.user} size={24} />
71
- ))}
72
- </label>
73
- )}
74
- </div>
75
- );
76
- }
@@ -1,28 +0,0 @@
1
- import { useSpace } from '@zenstackhq/runtime/hooks';
2
- import Link from 'next/link';
3
-
4
- export default function Spaces() {
5
- const { find } = useSpace();
6
- const spaces = find();
7
-
8
- return (
9
- <ul className="flex flex-wrap gap-4">
10
- {spaces.data?.map((space) => (
11
- <li
12
- className="card w-80 h-32 shadow-xl text-gray-600 cursor-pointer hover:bg-gray-50 border"
13
- key={space.id}
14
- >
15
- <Link href={`/space/${space.slug}`}>
16
- <a>
17
- <div className="card-body" title={space.name}>
18
- <h2 className="card-title line-clamp-1">
19
- {space.name}
20
- </h2>
21
- </div>
22
- </a>
23
- </Link>
24
- </li>
25
- ))}
26
- </ul>
27
- );
28
- }
@@ -1,17 +0,0 @@
1
- import moment from 'moment';
2
-
3
- type Props = {
4
- value: { createdAt: Date; updatedAt: Date; completedAt?: Date | null };
5
- };
6
-
7
- export default function TimeInfo({ value }: Props) {
8
- return (
9
- <p className="text-sm text-gray-500">
10
- {value.completedAt
11
- ? `Completed ${moment(value.completedAt).fromNow()}`
12
- : value.createdAt === value.updatedAt
13
- ? `Created ${moment(value.createdAt).fromNow()}`
14
- : `Updated ${moment(value.updatedAt).fromNow()}`}
15
- </p>
16
- );
17
- }
@@ -1,72 +0,0 @@
1
- import { TrashIcon } from '@heroicons/react/24/outline';
2
- import { useTodo } from '@zenstackhq/runtime/hooks';
3
- import { Todo, User } from '@zenstackhq/runtime/types';
4
- import { ChangeEvent, useEffect, useState } from 'react';
5
- import Avatar from './Avatar';
6
- import TimeInfo from './TimeInfo';
7
-
8
- type Props = {
9
- value: Todo & { owner: User };
10
- updated?: (value: Todo) => any;
11
- deleted?: (value: Todo) => any;
12
- };
13
-
14
- export default function Component({ value, updated, deleted }: Props) {
15
- const [completed, setCompleted] = useState(!!value.completedAt);
16
- const { update, del } = useTodo();
17
-
18
- useEffect(() => {
19
- if (!!value.completedAt !== completed) {
20
- update(value.id, {
21
- data: { completedAt: completed ? new Date() : null },
22
- }).then((newValue) => {
23
- if (updated) {
24
- updated(newValue);
25
- }
26
- });
27
- }
28
- });
29
-
30
- const deleteTodo = async () => {
31
- await del(value.id);
32
- if (deleted) {
33
- deleted(value);
34
- }
35
- };
36
-
37
- return (
38
- <div className="border rounded-lg px-8 py-4 shadow-lg flex flex-col items-center w-full lg:w-[480px]">
39
- <div className="flex justify-between w-full mb-4">
40
- <h3
41
- className={`text-xl line-clamp-1 ${
42
- value.completedAt
43
- ? 'line-through text-gray-400 italic'
44
- : 'text-gray-700'
45
- }`}
46
- >
47
- {value.title}
48
- </h3>
49
- <div className="flex">
50
- <input
51
- type="checkbox"
52
- className="checkbox mr-2"
53
- checked={completed}
54
- onChange={(e: ChangeEvent<HTMLInputElement>) =>
55
- setCompleted(e.currentTarget.checked)
56
- }
57
- />
58
- <TrashIcon
59
- className="w-6 h-6 text-gray-500 cursor-pointer"
60
- onClick={() => {
61
- deleteTodo();
62
- }}
63
- />
64
- </div>
65
- </div>
66
- <div className="flex justify-end w-full space-x-2">
67
- <TimeInfo value={value} />
68
- <Avatar user={value.owner} size={18} />
69
- </div>
70
- </div>
71
- );
72
- }
@@ -1,77 +0,0 @@
1
- import Image from 'next/image';
2
- import { List } from '@zenstackhq/runtime/types';
3
- import { customAlphabet } from 'nanoid';
4
- import { LockClosedIcon, TrashIcon } from '@heroicons/react/24/outline';
5
- import { User } from 'next-auth';
6
- import Avatar from './Avatar';
7
- import Link from 'next/link';
8
- import { useRouter } from 'next/router';
9
- import { useList } from '@zenstackhq/runtime/hooks';
10
- import TimeInfo from './TimeInfo';
11
-
12
- type Props = {
13
- value: List & { owner: User };
14
- deleted?: (value: List) => void;
15
- };
16
-
17
- export default function TodoList({ value, deleted }: Props) {
18
- const router = useRouter();
19
-
20
- const { del } = useList();
21
-
22
- const deleteList = async () => {
23
- if (confirm('Are you sure to delete this list?')) {
24
- await del(value.id);
25
- if (deleted) {
26
- deleted(value);
27
- }
28
- }
29
- };
30
-
31
- return (
32
- <div className="card w-80 bg-base-100 shadow-xl cursor-pointer hover:bg-gray-50">
33
- <Link href={`${router.asPath}/${value.id}`}>
34
- <a>
35
- <figure>
36
- <Image
37
- src={`https://picsum.photos/300/200?r=${customAlphabet(
38
- '0123456789'
39
- )(4)}`}
40
- width={320}
41
- height={200}
42
- alt="Cover"
43
- />
44
- </figure>
45
- </a>
46
- </Link>
47
- <div className="card-body">
48
- <Link href={`${router.asPath}/${value.id}`}>
49
- <a>
50
- <h2 className="card-title line-clamp-1">
51
- {value.title || 'Missing Title'}
52
- </h2>
53
- </a>
54
- </Link>
55
- <div className="card-actions flex w-full justify-between">
56
- <div>
57
- <TimeInfo value={value} />
58
- </div>
59
- <div className="flex space-x-2">
60
- <Avatar user={value.owner} size={18} />
61
- {value.private && (
62
- <div className="tooltip" data-tip="Private">
63
- <LockClosedIcon className="w-4 h-4 text-gray-500" />
64
- </div>
65
- )}
66
- <TrashIcon
67
- className="w-4 h-4 text-gray-500 cursor-pointer"
68
- onClick={() => {
69
- deleteList();
70
- }}
71
- />
72
- </div>
73
- </div>
74
- </div>
75
- </div>
76
- );
77
- }
@@ -1,31 +0,0 @@
1
- import { useSpace } from '@zenstackhq/runtime/hooks';
2
- import { Space } from '@zenstackhq/runtime/types';
3
- import { User } from 'next-auth';
4
- import { useSession } from 'next-auth/react';
5
- import { useRouter } from 'next/router';
6
- import { createContext } from 'react';
7
-
8
- export const UserContext = createContext<User | undefined>(undefined);
9
-
10
- export function useCurrentUser() {
11
- const { data: session } = useSession();
12
- return session?.user;
13
- }
14
-
15
- export const SpaceContext = createContext<Space | undefined>(undefined);
16
-
17
- export function useCurrentSpace() {
18
- const router = useRouter();
19
- const { find } = useSpace();
20
- const spaces = find({
21
- where: {
22
- slug: router.query.slug as string,
23
- },
24
- });
25
-
26
- if (!router.query.slug) {
27
- return undefined;
28
- }
29
-
30
- return spaces.data?.[0];
31
- }
@@ -1,10 +0,0 @@
1
- /** @type {import('next').NextConfig} */
2
- const nextConfig = {
3
- reactStrictMode: true,
4
- swcMinify: true,
5
- images: {
6
- domains: ['lh3.googleusercontent.com', 'picsum.photos'],
7
- },
8
- };
9
-
10
- module.exports = nextConfig;