@nocobase/portal-template-default 1.0.0

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 (123) hide show
  1. package/.env.example +10 -0
  2. package/Dockerfile +36 -0
  3. package/README.MD +50 -0
  4. package/components.json +25 -0
  5. package/eslint.config.js +28 -0
  6. package/index.html +39 -0
  7. package/package.json +84 -0
  8. package/pnpm-workspace.yaml +2 -0
  9. package/public/favicon.ico +0 -0
  10. package/public/logo-dark.png +0 -0
  11. package/public/logo-mark-dark.png +0 -0
  12. package/public/logo-mark.png +0 -0
  13. package/public/logo.png +0 -0
  14. package/src/App.css +158 -0
  15. package/src/App.tsx +151 -0
  16. package/src/components/app-shell/brand.tsx +70 -0
  17. package/src/components/app-shell/breadcrumb.tsx +81 -0
  18. package/src/components/app-shell/document-title-handler.tsx +169 -0
  19. package/src/components/app-shell/error-component.tsx +134 -0
  20. package/src/components/app-shell/header.tsx +127 -0
  21. package/src/components/app-shell/layout.tsx +39 -0
  22. package/src/components/app-shell/loading-overlay.tsx +36 -0
  23. package/src/components/app-shell/sidebar.tsx +351 -0
  24. package/src/components/app-shell/user-avatar.tsx +42 -0
  25. package/src/components/app-shell/user-info.tsx +53 -0
  26. package/src/components/auth/auth-layout.tsx +82 -0
  27. package/src/components/auth/forgot-password-form.tsx +58 -0
  28. package/src/components/auth/input-password.tsx +38 -0
  29. package/src/components/auth/sign-in-form.tsx +111 -0
  30. package/src/components/auth/sign-up-form.tsx +127 -0
  31. package/src/components/data-table/data-table-filter.tsx +994 -0
  32. package/src/components/data-table/data-table-pagination.tsx +146 -0
  33. package/src/components/data-table/data-table-sorter.tsx +47 -0
  34. package/src/components/data-table/data-table.tsx +321 -0
  35. package/src/components/notifications/toaster.tsx +23 -0
  36. package/src/components/notifications/undoable-notification.tsx +84 -0
  37. package/src/components/notifications/use-notification-provider.tsx +62 -0
  38. package/src/components/resources/buttons/clone.tsx +81 -0
  39. package/src/components/resources/buttons/create.tsx +70 -0
  40. package/src/components/resources/buttons/delete.tsx +113 -0
  41. package/src/components/resources/buttons/edit.tsx +81 -0
  42. package/src/components/resources/buttons/list.tsx +70 -0
  43. package/src/components/resources/buttons/refresh.tsx +81 -0
  44. package/src/components/resources/buttons/show.tsx +81 -0
  45. package/src/components/resources/status-badge.tsx +37 -0
  46. package/src/components/resources/views/create-view.tsx +81 -0
  47. package/src/components/resources/views/edit-view.tsx +104 -0
  48. package/src/components/resources/views/list-view.tsx +86 -0
  49. package/src/components/resources/views/show-view.tsx +108 -0
  50. package/src/components/theme/theme-provider.tsx +71 -0
  51. package/src/components/theme/theme-select.tsx +97 -0
  52. package/src/components/theme/theme-toggle.tsx +66 -0
  53. package/src/components/ui/accordion.tsx +72 -0
  54. package/src/components/ui/alert-dialog.tsx +185 -0
  55. package/src/components/ui/alert.tsx +76 -0
  56. package/src/components/ui/aspect-ratio.tsx +22 -0
  57. package/src/components/ui/avatar.tsx +107 -0
  58. package/src/components/ui/badge.tsx +52 -0
  59. package/src/components/ui/breadcrumb.tsx +125 -0
  60. package/src/components/ui/button.tsx +58 -0
  61. package/src/components/ui/calendar.tsx +221 -0
  62. package/src/components/ui/card.tsx +103 -0
  63. package/src/components/ui/carousel.tsx +240 -0
  64. package/src/components/ui/chart.tsx +373 -0
  65. package/src/components/ui/checkbox.tsx +29 -0
  66. package/src/components/ui/collapsible.tsx +19 -0
  67. package/src/components/ui/command.tsx +192 -0
  68. package/src/components/ui/context-menu.tsx +271 -0
  69. package/src/components/ui/dialog.tsx +160 -0
  70. package/src/components/ui/drawer.tsx +226 -0
  71. package/src/components/ui/dropdown-menu.tsx +268 -0
  72. package/src/components/ui/form.tsx +174 -0
  73. package/src/components/ui/hover-card.tsx +49 -0
  74. package/src/components/ui/input-group.tsx +158 -0
  75. package/src/components/ui/input-otp.tsx +87 -0
  76. package/src/components/ui/input.tsx +20 -0
  77. package/src/components/ui/label.tsx +18 -0
  78. package/src/components/ui/menubar.tsx +278 -0
  79. package/src/components/ui/navigation-menu.tsx +168 -0
  80. package/src/components/ui/pagination.tsx +130 -0
  81. package/src/components/ui/popover.tsx +91 -0
  82. package/src/components/ui/progress.tsx +81 -0
  83. package/src/components/ui/radio-group.tsx +38 -0
  84. package/src/components/ui/resizable.tsx +48 -0
  85. package/src/components/ui/scroll-area.tsx +55 -0
  86. package/src/components/ui/select.tsx +199 -0
  87. package/src/components/ui/separator.tsx +25 -0
  88. package/src/components/ui/sheet.tsx +136 -0
  89. package/src/components/ui/sidebar.tsx +723 -0
  90. package/src/components/ui/skeleton.tsx +13 -0
  91. package/src/components/ui/slider.tsx +52 -0
  92. package/src/components/ui/sonner.tsx +47 -0
  93. package/src/components/ui/switch.tsx +32 -0
  94. package/src/components/ui/table.tsx +114 -0
  95. package/src/components/ui/tabs.tsx +82 -0
  96. package/src/components/ui/textarea.tsx +18 -0
  97. package/src/components/ui/toggle-group.tsx +87 -0
  98. package/src/components/ui/toggle.tsx +43 -0
  99. package/src/components/ui/tooltip.tsx +66 -0
  100. package/src/hooks/use-mobile.ts +19 -0
  101. package/src/index.tsx +17 -0
  102. package/src/lib/utils.ts +19 -0
  103. package/src/pages/blog-posts/create.tsx +177 -0
  104. package/src/pages/blog-posts/edit.tsx +197 -0
  105. package/src/pages/blog-posts/index.ts +4 -0
  106. package/src/pages/blog-posts/list.tsx +131 -0
  107. package/src/pages/blog-posts/show.tsx +81 -0
  108. package/src/pages/categories/create.tsx +73 -0
  109. package/src/pages/categories/edit.tsx +73 -0
  110. package/src/pages/categories/index.ts +4 -0
  111. package/src/pages/categories/list.tsx +86 -0
  112. package/src/pages/categories/show.tsx +37 -0
  113. package/src/pages/forgot-password/index.tsx +6 -0
  114. package/src/pages/forgotPassword/index.tsx +5 -0
  115. package/src/pages/login/index.tsx +5 -0
  116. package/src/pages/register/index.tsx +5 -0
  117. package/src/providers/auth.ts +204 -0
  118. package/src/providers/constants.ts +75 -0
  119. package/src/providers/data.ts +232 -0
  120. package/src/vite-env.d.ts +1 -0
  121. package/tsconfig.json +25 -0
  122. package/tsconfig.node.json +21 -0
  123. package/vite.config.ts +74 -0
@@ -0,0 +1,111 @@
1
+ "use client";
2
+
3
+ import { useState } from "react";
4
+ import { Chrome, Github } from "lucide-react";
5
+ import { useLink, useLogin } from "@refinedev/core";
6
+
7
+ import { AuthLayout } from "@/components/auth/auth-layout";
8
+ import { InputPassword } from "@/components/auth/input-password";
9
+ import { Button } from "@/components/ui/button";
10
+ import { Input } from "@/components/ui/input";
11
+ import { Label } from "@/components/ui/label";
12
+
13
+ export const SignInForm = () => {
14
+ const [account, setAccount] = useState("");
15
+ const [password, setPassword] = useState("");
16
+ const Link = useLink();
17
+ const { mutate: login } = useLogin();
18
+
19
+ const handleSignIn = (event: React.FormEvent<HTMLFormElement>) => {
20
+ event.preventDefault();
21
+ login({ username: account, password });
22
+ };
23
+
24
+ return (
25
+ <AuthLayout
26
+ title="Welcome back"
27
+ description="Use your NocoBase account to continue."
28
+ >
29
+ <form onSubmit={handleSignIn} className="space-y-5">
30
+ <div className="space-y-2">
31
+ <Label htmlFor="account">Username or email</Label>
32
+ <Input
33
+ id="account"
34
+ type="text"
35
+ value={account}
36
+ onChange={(event) => setAccount(event.target.value)}
37
+ autoComplete="username"
38
+ autoFocus
39
+ required
40
+ className="h-11 rounded-lg"
41
+ />
42
+ </div>
43
+
44
+ <div className="space-y-2">
45
+ <Label htmlFor="password">Password</Label>
46
+ <InputPassword
47
+ id="password"
48
+ value={password}
49
+ onChange={(event) => setPassword(event.target.value)}
50
+ autoComplete="current-password"
51
+ required
52
+ className="h-11 rounded-lg"
53
+ />
54
+ </div>
55
+
56
+ <Button type="submit" size="lg" className="h-11 w-full rounded-lg">
57
+ Sign in
58
+ </Button>
59
+
60
+ <div className="flex flex-wrap items-center justify-between gap-x-4 gap-y-2 text-sm text-muted-foreground">
61
+ <Link
62
+ to="/forgot-password"
63
+ className="transition-colors hover:text-foreground hover:underline hover:underline-offset-4"
64
+ >
65
+ Forgot password?
66
+ </Link>
67
+ <span>
68
+ No account?{" "}
69
+ <Link
70
+ to="/register"
71
+ className="font-semibold text-foreground underline underline-offset-4"
72
+ >
73
+ Sign up
74
+ </Link>
75
+ </span>
76
+ </div>
77
+
78
+ <div className="flex items-center gap-4 py-1">
79
+ <div className="h-px flex-1 bg-border" />
80
+ <span className="text-xs text-muted-foreground">
81
+ Or continue with
82
+ </span>
83
+ <div className="h-px flex-1 bg-border" />
84
+ </div>
85
+
86
+ <div className="grid grid-cols-2 gap-3">
87
+ <Button
88
+ type="button"
89
+ variant="outline"
90
+ className="h-10 rounded-lg"
91
+ onClick={() => login({ providerName: "google" })}
92
+ >
93
+ <Chrome />
94
+ Google
95
+ </Button>
96
+ <Button
97
+ type="button"
98
+ variant="outline"
99
+ className="h-10 rounded-lg"
100
+ onClick={() => login({ providerName: "github" })}
101
+ >
102
+ <Github />
103
+ GitHub
104
+ </Button>
105
+ </div>
106
+ </form>
107
+ </AuthLayout>
108
+ );
109
+ };
110
+
111
+ SignInForm.displayName = "SignInForm";
@@ -0,0 +1,127 @@
1
+ "use client";
2
+
3
+ import { useState } from "react";
4
+ import { Chrome, Github } from "lucide-react";
5
+ import { useLink, useNotification, useRegister } from "@refinedev/core";
6
+
7
+ import { AuthLayout } from "@/components/auth/auth-layout";
8
+ import { InputPassword } from "@/components/auth/input-password";
9
+ import { Button } from "@/components/ui/button";
10
+ import { Input } from "@/components/ui/input";
11
+ import { Label } from "@/components/ui/label";
12
+
13
+ export const SignUpForm = () => {
14
+ const [email, setEmail] = useState("");
15
+ const [password, setPassword] = useState("");
16
+ const [confirmPassword, setConfirmPassword] = useState("");
17
+ const { open } = useNotification();
18
+ const Link = useLink();
19
+ const { mutate: register } = useRegister();
20
+
21
+ const handleSignUp = (event: React.FormEvent<HTMLFormElement>) => {
22
+ event.preventDefault();
23
+
24
+ if (password !== confirmPassword) {
25
+ open?.({
26
+ type: "error",
27
+ message: "Passwords don't match",
28
+ description: "Please make sure both password fields match.",
29
+ });
30
+ return;
31
+ }
32
+
33
+ register({ email, password });
34
+ };
35
+
36
+ return (
37
+ <AuthLayout
38
+ title="Create your account"
39
+ description="Create your NocoBase account."
40
+ >
41
+ <form onSubmit={handleSignUp} className="space-y-5">
42
+ <div className="space-y-2">
43
+ <Label htmlFor="email">Email</Label>
44
+ <Input
45
+ id="email"
46
+ type="email"
47
+ value={email}
48
+ onChange={(event) => setEmail(event.target.value)}
49
+ autoComplete="email"
50
+ autoFocus
51
+ required
52
+ className="h-11 rounded-lg"
53
+ />
54
+ </div>
55
+
56
+ <div className="space-y-2">
57
+ <Label htmlFor="password">Password</Label>
58
+ <InputPassword
59
+ id="password"
60
+ value={password}
61
+ onChange={(event) => setPassword(event.target.value)}
62
+ autoComplete="new-password"
63
+ required
64
+ className="h-11 rounded-lg"
65
+ />
66
+ </div>
67
+
68
+ <div className="space-y-2">
69
+ <Label htmlFor="confirmPassword">Confirm password</Label>
70
+ <InputPassword
71
+ id="confirmPassword"
72
+ value={confirmPassword}
73
+ onChange={(event) => setConfirmPassword(event.target.value)}
74
+ autoComplete="new-password"
75
+ required
76
+ className="h-11 rounded-lg"
77
+ />
78
+ </div>
79
+
80
+ <Button type="submit" size="lg" className="h-11 w-full rounded-lg">
81
+ Sign up
82
+ </Button>
83
+
84
+ <p className="text-center text-sm text-muted-foreground">
85
+ Have an account?{" "}
86
+ <Link
87
+ to="/login"
88
+ className="font-semibold text-foreground underline underline-offset-4"
89
+ >
90
+ Sign in
91
+ </Link>
92
+ </p>
93
+
94
+ <div className="flex items-center gap-4 py-1">
95
+ <div className="h-px flex-1 bg-border" />
96
+ <span className="text-xs text-muted-foreground">
97
+ Or continue with
98
+ </span>
99
+ <div className="h-px flex-1 bg-border" />
100
+ </div>
101
+
102
+ <div className="grid grid-cols-2 gap-3">
103
+ <Button
104
+ type="button"
105
+ variant="outline"
106
+ className="h-10 rounded-lg"
107
+ onClick={() => register({ providerName: "google" })}
108
+ >
109
+ <Chrome />
110
+ Google
111
+ </Button>
112
+ <Button
113
+ type="button"
114
+ variant="outline"
115
+ className="h-10 rounded-lg"
116
+ onClick={() => register({ providerName: "github" })}
117
+ >
118
+ <Github />
119
+ GitHub
120
+ </Button>
121
+ </div>
122
+ </form>
123
+ </AuthLayout>
124
+ );
125
+ };
126
+
127
+ SignUpForm.displayName = "SignUpForm";