create-cundi-app 1.0.0 → 1.0.3

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.
package/README.md CHANGED
@@ -1,8 +1,10 @@
1
1
  # create-cundi-app
2
2
 
3
- Create a new Cundi app with React + Refine + Ant Design.
3
+ Create a new Cundi web application with React + Refine + Ant Design.
4
4
 
5
- ## Usage
5
+ [![npm version](https://img.shields.io/npm/v/create-cundi-app.svg)](https://www.npmjs.com/package/create-cundi-app)
6
+
7
+ ## Quick Start
6
8
 
7
9
  ```bash
8
10
  # Using npm
@@ -22,48 +24,55 @@ pnpm create cundi-app my-app
22
24
 
23
25
  The generated project includes:
24
26
 
25
- - **Framework**: React 19 + TypeScript
26
- - **Build Tool**: Vite
27
- - **UI Library**: Ant Design
28
- - **Metasystem**: [Refine](https://refine.dev/)
29
- - **Core SDK**: `@cundi/refine-xaf`
27
+ | Category | Technology |
28
+ |----------|------------|
29
+ | Framework | React 19 + TypeScript |
30
+ | Build Tool | Vite |
31
+ | UI Library | Ant Design |
32
+ | Metasystem | [Refine](https://refine.dev/) |
33
+ | Core SDK | [@cundi/refine-xaf](https://www.npmjs.com/package/@cundi/refine-xaf) |
30
34
 
31
35
  ### Features
32
36
 
33
- - 🔐 Authentication (Local + Keycloak SSO)
34
- - 👤 User Management
35
- - 🛡️ Role-based Access Control
36
- - 🌍 Internationalization (i18n)
37
- - 🌙 Dark Mode Support
38
- - 📊 Dashboard Template
37
+ - 🔐 **Dual Authentication**: Local login + Keycloak SSO
38
+ - 👤 **User Management**: Pre-built user CRUD pages
39
+ - 🛡️ **RBAC**: Role-based Access Control
40
+ - 🌍 **i18n**: English and Traditional Chinese
41
+ - 🌙 **Dark Mode**: Theme toggle support
42
+ - 📊 **Dashboard**: Starter template
39
43
 
40
44
  ## After Creating
41
45
 
42
- 1. Navigate to your project:
43
- ```bash
44
- cd my-app
45
- ```
46
+ ```bash
47
+ cd my-app
48
+ npm install
49
+ cp .env.example .env # Configure your API URL
50
+ npm run dev
51
+ ```
46
52
 
47
- 2. Install dependencies:
48
- ```bash
49
- npm install
50
- ```
53
+ ### Environment Variables
51
54
 
52
- 3. Configure environment:
53
- ```bash
54
- cp .env.example .env
55
- # Edit .env with your API URL and Keycloak settings
56
- ```
55
+ Edit `.env` to configure:
57
56
 
58
- 4. Start development server:
59
- ```bash
60
- npm run dev
61
- ```
57
+ ```env
58
+ VITE_API_URL=http://localhost:5000/api
59
+
60
+ # Keycloak (Optional)
61
+ VITE_KEYCLOAK_URL=http://localhost:8080
62
+ VITE_KEYCLOAK_REALM=your-realm
63
+ VITE_KEYCLOAK_CLIENT_ID=your-client-id
64
+ VITE_REDIRECT_URI=http://localhost:5173/auth/callback
65
+ ```
62
66
 
63
67
  ## Documentation
64
68
 
65
- - [Refine Documentation](https://refine.dev/docs/)
69
+ - [Cundi Development Guide](https://github.com/antonylu0826/Cundi/blob/main/Development_Guide.md)
66
70
  - [@cundi/refine-xaf SDK](https://www.npmjs.com/package/@cundi/refine-xaf)
71
+ - [Refine Documentation](https://refine.dev/docs/)
72
+
73
+ ## Related
74
+
75
+ - [cundiapi](https://www.nuget.org/packages/Cundi.Api.Template) - Backend template for .NET
67
76
 
68
77
  ## License
69
78
 
package/index.js CHANGED
@@ -114,13 +114,19 @@ VITE_REDIRECT_URI=http://localhost:5173/auth/callback
114
114
  await fs.rename(gitignoreSrc, gitignoreDest);
115
115
  }
116
116
 
117
+ // Create .env from .env.example
118
+ const envPath = path.join(targetDir, ".env");
119
+ if (fs.existsSync(envExamplePath) && !fs.existsSync(envPath)) {
120
+ await fs.copy(envExamplePath, envPath);
121
+ }
122
+
117
123
  console.log(kleur.green("✔ Project created successfully!"));
118
124
  console.log();
119
125
  console.log(kleur.cyan("Next steps:"));
120
126
  console.log();
121
127
  console.log(` ${kleur.gray("$")} cd ${projectName}`);
122
128
  console.log(` ${kleur.gray("$")} npm install`);
123
- console.log(` ${kleur.gray("$")} cp .env.example .env ${kleur.gray("# Configure your environment")}`);
129
+ // console.log(` ${kleur.gray("$")} cp .env.example .env ${kleur.gray("# Configure your environment")}`);
124
130
  console.log(` ${kleur.gray("$")} npm run dev`);
125
131
  console.log();
126
132
  console.log(kleur.gray("────────────────────────────────────"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-cundi-app",
3
- "version": "1.0.0",
3
+ "version": "1.0.3",
4
4
  "description": "Create a new Cundi app with React + Refine + Ant Design",
5
5
  "type": "module",
6
6
  "bin": {
@@ -10,6 +10,9 @@
10
10
  "index.js",
11
11
  "template"
12
12
  ],
13
+ "scripts": {
14
+ "pack": "npm pack --pack-destination ../../output/npm"
15
+ },
13
16
  "keywords": [
14
17
  "create",
15
18
  "cundi",
@@ -34,4 +37,4 @@
34
37
  "engines": {
35
38
  "node": ">=18"
36
39
  }
37
- }
40
+ }
@@ -24,7 +24,7 @@
24
24
  "dependencies": {
25
25
  "@ant-design/icons": "^5.5.1",
26
26
  "@ant-design/v5-patch-for-react-19": "^1.0.3",
27
- "@cundi/refine-xaf": "^1.0.3",
27
+ "@cundi/refine-xaf": "^1.0.6",
28
28
  "@refinedev/antd": "^6.0.3",
29
29
  "@refinedev/cli": "^2.16.50",
30
30
  "@refinedev/core": "^5.0.6",
@@ -6,13 +6,13 @@ import {
6
6
  useNotificationProvider,
7
7
  ThemedLayout,
8
8
  ErrorComponent,
9
- RefineThemes,
10
9
  } from "@refinedev/antd";
11
10
  import {
12
11
  DashboardOutlined,
13
12
  UserOutlined,
14
13
  SettingOutlined,
15
14
  TeamOutlined,
15
+ FieldTimeOutlined,
16
16
  } from "@ant-design/icons";
17
17
 
18
18
  import routerProvider, {
@@ -22,7 +22,7 @@ import routerProvider, {
22
22
  DocumentTitleHandler,
23
23
  } from "@refinedev/react-router";
24
24
  import { BrowserRouter, Routes, Route, Outlet } from "react-router";
25
- import { App as AntdApp, ConfigProvider, theme } from "antd";
25
+ import { App as AntdApp } from "antd";
26
26
  import { useTranslation } from "react-i18next";
27
27
  import "./i18n";
28
28
 
@@ -43,15 +43,15 @@ import {
43
43
  RoleList,
44
44
  RoleCreate,
45
45
  RoleEdit,
46
+ ColorModeContextProvider,
47
+ BackgroundJobList,
46
48
  } from "@cundi/refine-xaf";
47
49
 
48
- import { ColorModeContextProvider, useColorMode } from "./contexts/color-mode";
49
50
  import { accessControlProvider } from "./accessControlProvider";
50
51
 
51
52
  const API_URL = import.meta.env.VITE_API_URL + "/odata";
52
53
 
53
54
  const InnerApp: React.FC = () => {
54
- const { mode } = useColorMode();
55
55
  const { t, i18n } = useTranslation();
56
56
 
57
57
  const i18nProvider = {
@@ -62,121 +62,125 @@ const InnerApp: React.FC = () => {
62
62
 
63
63
  return (
64
64
  <BrowserRouter>
65
- <ConfigProvider
66
- theme={{
67
- ...RefineThemes.Blue,
68
- algorithm: mode === "dark" ? theme.darkAlgorithm : theme.defaultAlgorithm,
69
- }}
70
- >
71
- <AntdApp>
72
- <Refine
73
- authProvider={authProvider}
74
- accessControlProvider={accessControlProvider}
75
- dataProvider={dataProvider(API_URL)}
76
- i18nProvider={i18nProvider}
77
- routerProvider={routerProvider}
78
- resources={[
79
- {
80
- name: "dashboard",
81
- list: "/",
82
- meta: {
83
- label: t("sider.dashboard"),
84
- icon: <DashboardOutlined />,
85
- },
65
+ <AntdApp>
66
+ <Refine
67
+ authProvider={authProvider}
68
+ accessControlProvider={accessControlProvider}
69
+ dataProvider={dataProvider(API_URL)}
70
+ i18nProvider={i18nProvider}
71
+ routerProvider={routerProvider}
72
+ resources={[
73
+ {
74
+ name: "dashboard",
75
+ list: "/",
76
+ meta: {
77
+ label: t("sider.dashboard"),
78
+ icon: <DashboardOutlined />,
86
79
  },
87
- {
88
- name: "ApplicationUser",
89
- list: "/ApplicationUsers",
90
- create: "/ApplicationUsers/create",
91
- edit: "/ApplicationUsers/edit/:id",
92
- meta: {
93
- label: t("sider.users"),
94
- icon: <UserOutlined />,
95
- parent: t("sider.settings"),
96
- },
80
+ },
81
+ {
82
+ name: "ApplicationUser",
83
+ list: "/ApplicationUsers",
84
+ create: "/ApplicationUsers/create",
85
+ edit: "/ApplicationUsers/edit/:id",
86
+ meta: {
87
+ label: t("sider.users"),
88
+ icon: <UserOutlined />,
89
+ parent: t("sider.settings"),
97
90
  },
98
- {
99
- name: "PermissionPolicyRole",
100
- list: "/PermissionPolicyRoles",
101
- create: "/PermissionPolicyRoles/create",
102
- edit: "/PermissionPolicyRoles/edit/:id",
103
- meta: {
104
- label: t("sider.roles"),
105
- parent: t("sider.settings"),
106
- icon: <TeamOutlined />,
107
- },
91
+ },
92
+ {
93
+ name: "PermissionPolicyRole",
94
+ list: "/PermissionPolicyRoles",
95
+ create: "/PermissionPolicyRoles/create",
96
+ edit: "/PermissionPolicyRoles/edit/:id",
97
+ meta: {
98
+ label: t("sider.roles"),
99
+ parent: t("sider.settings"),
100
+ icon: <TeamOutlined />,
108
101
  },
109
- {
110
- name: "Settings",
111
- meta: {
112
- label: t("sider.settings"),
113
- icon: <SettingOutlined />,
114
- },
102
+ },
103
+ {
104
+ name: "BackgroundJobs",
105
+ list: "/background-jobs",
106
+ meta: {
107
+ label: t("sider.backgroundJobs"),
108
+ icon: <FieldTimeOutlined />,
109
+ parent: t("sider.settings"),
115
110
  },
116
- ]}
117
- notificationProvider={useNotificationProvider}
118
- options={{
119
- syncWithLocation: true,
120
- warnWhenUnsavedChanges: true,
121
- }}
122
- >
123
- <Routes>
124
- <Route
125
- element={
126
- <Authenticated
127
- key="authenticated-routes"
128
- fallback={<CatchAllNavigate to="/login" />}
129
- >
130
- <ThemedLayout Header={Header}>
131
- <Outlet />
132
- </ThemedLayout>
133
- </Authenticated>
134
- }
135
- >
136
- <Route index element={<DashboardPage />} />
137
-
138
- <Route path="/ApplicationUsers">
139
- <Route index element={<ApplicationUserList />} />
140
- <Route path="create" element={<ApplicationUserCreate />} />
141
- <Route path="edit/:id" element={<ApplicationUserEdit />} />
142
- </Route>
111
+ },
112
+ {
113
+ name: "Settings",
114
+ meta: {
115
+ label: t("sider.settings"),
116
+ icon: <SettingOutlined />,
117
+ },
118
+ },
119
+ ]}
120
+ notificationProvider={useNotificationProvider}
121
+ options={{
122
+ syncWithLocation: true,
123
+ warnWhenUnsavedChanges: true,
124
+ }}
125
+ >
126
+ <Routes>
127
+ <Route
128
+ element={
129
+ <Authenticated
130
+ key="authenticated-routes"
131
+ fallback={<CatchAllNavigate to="/login" />}
132
+ >
133
+ <ThemedLayout Header={Header}>
134
+ <Outlet />
135
+ </ThemedLayout>
136
+ </Authenticated>
137
+ }
138
+ >
139
+ <Route index element={<DashboardPage />} />
143
140
 
144
- <Route path="/PermissionPolicyRoles">
145
- <Route index element={<RoleList />} />
146
- <Route path="create" element={<RoleCreate />} />
147
- <Route path="edit/:id" element={<RoleEdit />} />
148
- </Route>
141
+ <Route path="/ApplicationUsers">
142
+ <Route index element={<ApplicationUserList />} />
143
+ <Route path="create" element={<ApplicationUserCreate />} />
144
+ <Route path="edit/:id" element={<ApplicationUserEdit />} />
149
145
  </Route>
150
146
 
151
- <Route
152
- element={
153
- <Authenticated key="auth-pages" fallback={<Outlet />}>
154
- <NavigateToResource resource="dashboard" />
155
- </Authenticated>
156
- }
157
- >
158
- <Route path="/login" element={<KeycloakLoginPage />} />
159
- <Route path="/login/api" element={<LoginPage />} />
160
- <Route path="/auth/callback" element={<AuthCallback />} />
147
+ <Route path="/PermissionPolicyRoles">
148
+ <Route index element={<RoleList />} />
149
+ <Route path="create" element={<RoleCreate />} />
150
+ <Route path="edit/:id" element={<RoleEdit />} />
161
151
  </Route>
162
152
 
163
- <Route
164
- element={
165
- <Authenticated key="catch-all">
166
- <ThemedLayout Header={Header}>
167
- <Outlet />
168
- </ThemedLayout>
169
- </Authenticated>
170
- }
171
- >
172
- <Route path="*" element={<ErrorComponent />} />
173
- </Route>
174
- </Routes>
175
- <UnsavedChangesNotifier />
176
- <DocumentTitleHandler />
177
- </Refine>
178
- </AntdApp>
179
- </ConfigProvider>
153
+ <Route path="/background-jobs" element={<BackgroundJobList title={t("sider.backgroundJobs")} />} />
154
+ </Route>
155
+
156
+ <Route
157
+ element={
158
+ <Authenticated key="auth-pages" fallback={<Outlet />}>
159
+ <NavigateToResource resource="dashboard" />
160
+ </Authenticated>
161
+ }
162
+ >
163
+ <Route path="/login" element={<KeycloakLoginPage />} />
164
+ <Route path="/login/api" element={<LoginPage />} />
165
+ <Route path="/auth/callback" element={<AuthCallback />} />
166
+ </Route>
167
+
168
+ <Route
169
+ element={
170
+ <Authenticated key="catch-all">
171
+ <ThemedLayout Header={Header}>
172
+ <Outlet />
173
+ </ThemedLayout>
174
+ </Authenticated>
175
+ }
176
+ >
177
+ <Route path="*" element={<ErrorComponent />} />
178
+ </Route>
179
+ </Routes>
180
+ <UnsavedChangesNotifier />
181
+ <DocumentTitleHandler />
182
+ </Refine>
183
+ </AntdApp>
180
184
  </BrowserRouter>
181
185
  );
182
186
  };
@@ -4,6 +4,17 @@ import react from "@vitejs/plugin-react";
4
4
  export default defineConfig({
5
5
  plugins: [react()],
6
6
  resolve: {
7
+ alias: {
8
+ "antd/lib": "antd",
9
+ },
7
10
  dedupe: ["react", "react-dom", "antd", "@refinedev/core", "@refinedev/antd", "@tanstack/react-query"],
8
11
  },
12
+ server: {
13
+ proxy: {
14
+ "/api": {
15
+ target: "http://localhost:5000",
16
+ changeOrigin: true,
17
+ },
18
+ },
19
+ },
9
20
  });
@@ -1,2 +0,0 @@
1
- import { ColorModeContextProvider, useColorMode } from "@cundi/refine-xaf";
2
- export { ColorModeContextProvider, useColorMode };