@fluid-app/fluid-cli-portal 0.1.31 → 0.1.33
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/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +51 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/templates/base/.gitignore.template +27 -0
- package/templates/base/AGENTS.md +36 -0
- package/templates/base/skills/fluid-portal-authoring/SKILL.md +153 -0
- package/templates/base/src/main.tsx +2 -2
- package/templates/base/src/portal.config.ts +8 -34
- package/templates/starter/README.md.template +122 -181
- package/templates/base/src/navigation.config.ts +0 -26
- package/templates/base/src/screens/Dashboard.tsx +0 -133
- package/templates/base/src/screens/ExampleForm.tsx +0 -177
|
@@ -1,243 +1,184 @@
|
|
|
1
1
|
# {{projectName}}
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A Fluid portal shell built with `@fluid-app/portal-sdk` and the Fluid portal CLI.
|
|
4
4
|
|
|
5
|
-
This is the
|
|
5
|
+
This starter is designed for the Fluid OS definition workflow: pull the portal definition into local JSON, edit `portal/`, push the working/draft definition back to Fluid OS, then create and activate a version when it should go live.
|
|
6
6
|
|
|
7
|
-
## What's
|
|
7
|
+
## What's included
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
9
|
+
- **Portal shell** — Vite builds the hosted SDK shell assets.
|
|
10
|
+
- **Portal definition sync** — `pnpm pull` and `pnpm push` manage local Fluid OS JSON under `portal/`.
|
|
11
|
+
- **Deployment workflow** — GitHub Actions can build and upload the hosted shell assets in `dist/`.
|
|
12
|
+
- **Widget authoring support** — `pnpm widget:create <name>` scaffolds company-owned portal widgets.
|
|
13
|
+
- **AI authoring kit** — generated `AGENTS.md`, `CLAUDE.md`, `.agents/skills/...`, and `.claude/skills/...` files explain the supported portal and widget workflows.
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
- **Dashboard** - Overview screen demonstrating:
|
|
15
|
-
- TextWidget - Welcome message and tips
|
|
16
|
-
- ToDoWidget - Task list (uses `useTodos` hook)
|
|
17
|
-
- RecentActivityWidget - Activity feed (uses `useActivities` hook)
|
|
18
|
-
- ChartWidget - Performance visualization
|
|
19
|
-
- CalendarWidget - Event calendar (uses `useCalendarEvents` hook)
|
|
20
|
-
|
|
21
|
-
## Getting Started
|
|
22
|
-
|
|
23
|
-
### Development
|
|
24
|
-
|
|
25
|
-
Start the development server:
|
|
15
|
+
## Quick start
|
|
26
16
|
|
|
27
17
|
```bash
|
|
18
|
+
pnpm install
|
|
19
|
+
pnpm pull
|
|
28
20
|
pnpm dev
|
|
29
21
|
```
|
|
30
22
|
|
|
31
|
-
Open [http://localhost:5173](http://localhost:5173)
|
|
32
|
-
|
|
33
|
-
### Building for Production
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
pnpm build
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
The output will be in the `dist/` folder.
|
|
23
|
+
Open the local URL printed by Vite, usually [http://localhost:5173](http://localhost:5173).
|
|
40
24
|
|
|
41
|
-
|
|
25
|
+
Useful commands:
|
|
42
26
|
|
|
43
27
|
```bash
|
|
44
|
-
pnpm
|
|
28
|
+
pnpm dev # Start Vite
|
|
29
|
+
pnpm build # TypeScript build plus production bundle
|
|
30
|
+
pnpm preview # Preview dist locally
|
|
31
|
+
pnpm typecheck # TypeScript checks
|
|
32
|
+
pnpm lint # OxLint
|
|
33
|
+
pnpm pull # fluid portal pull
|
|
34
|
+
pnpm push # fluid portal push
|
|
35
|
+
pnpm widget:create <name> # scaffold a company-owned portal widget
|
|
45
36
|
```
|
|
46
37
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
├──
|
|
54
|
-
├──
|
|
55
|
-
├── portal
|
|
56
|
-
├──
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
38
|
+
Set `VITE_API_URL` in `.env` if you need to point the SDK at a non-default Fluid API host.
|
|
39
|
+
|
|
40
|
+
## Project structure
|
|
41
|
+
|
|
42
|
+
```text
|
|
43
|
+
.
|
|
44
|
+
├── AGENTS.md # AI-agent guidance
|
|
45
|
+
├── CLAUDE.md # Bridge to AGENTS.md
|
|
46
|
+
├── .agents/skills/fluid-portal-authoring/ # Portal sync workflow skill
|
|
47
|
+
├── .agents/skills/fluid-widget-authoring/ # Widget authoring skill
|
|
48
|
+
├── .claude/skills/fluid-portal-authoring/ # Claude-compatible copy
|
|
49
|
+
├── .claude/skills/fluid-widget-authoring/ # Claude-compatible copy
|
|
50
|
+
├── .github/workflows/deploy.yml # Hosted shell asset deployment
|
|
51
|
+
├── src/
|
|
52
|
+
│ ├── main.tsx # createPortal bootstrap
|
|
53
|
+
│ ├── index.css # Tailwind and SDK globals
|
|
54
|
+
│ ├── portal.config.ts # SDK/widget package integration
|
|
55
|
+
│ ├── preview-entry.tsx # Builder/widget preview entry
|
|
56
|
+
│ └── widgets/ # Created by pnpm widget:create
|
|
57
|
+
├── portal/ # Created/refreshed by fluid portal pull
|
|
58
|
+
└── .portal-sync/ # Generated sync metadata
|
|
60
59
|
```
|
|
61
60
|
|
|
62
|
-
##
|
|
61
|
+
## Supported portal authoring workflow
|
|
63
62
|
|
|
64
|
-
|
|
63
|
+
### 1. Pull remote Fluid OS definitions
|
|
65
64
|
|
|
66
|
-
|
|
65
|
+
```bash
|
|
66
|
+
pnpm pull
|
|
67
|
+
```
|
|
67
68
|
|
|
68
|
-
|
|
69
|
-
2. **Build** — runs `pnpm build`, producing stable filenames (`portal.js`, `portal.css`)
|
|
70
|
-
3. **Upload** — syncs `dist/` to `gs://portals-cdn/{{projectName}}/assets/` via `gcloud storage rsync`
|
|
71
|
-
4. **Invalidate** — clears the CDN cache for your tenant's asset prefix
|
|
69
|
+
This runs `fluid portal pull` and writes `portal/` plus `.portal-sync/`.
|
|
72
70
|
|
|
73
|
-
|
|
71
|
+
- `portal/` contains local JSON for Fluid OS resources such as screens, themes, navigations, profiles, and definition metadata.
|
|
72
|
+
- `.portal-sync/` contains generated sync state for future diffs. Do not edit it by hand.
|
|
74
73
|
|
|
75
|
-
|
|
76
|
-
2. Add the service account JSON key as a GitHub Actions secret named `GCP_SA_JSON`
|
|
77
|
-
3. Set `CDN_HOSTNAME` in `.github/workflows/deploy.yml` to your Cloud CDN load balancer's frontend domain
|
|
78
|
-
4. Update `GCP_PROJECT` and `CDN_URL_MAP` if your project differs from the defaults
|
|
74
|
+
Pull before editing unless you intentionally want to work from the current local JSON.
|
|
79
75
|
|
|
80
|
-
###
|
|
76
|
+
### 2. Edit `portal/` JSON
|
|
81
77
|
|
|
82
|
-
|
|
83
|
-
|----------|-------|---------|
|
|
84
|
-
| `GCP_SA_JSON` | GitHub secret | GCP service account credentials |
|
|
85
|
-
| `GCP_PROJECT` | Workflow env | Google Cloud project ID |
|
|
86
|
-
| `CDN_URL_MAP` | Workflow env | Cloud CDN URL map name for cache invalidation |
|
|
87
|
-
| `CDN_HOSTNAME` | Workflow env | CDN frontend domain (load balancer hostname) |
|
|
88
|
-
| `VITE_ASSET_BASE` | Build env | Derived from `CDN_HOSTNAME` (set automatically) |
|
|
78
|
+
Make portal definition changes inside `portal/`.
|
|
89
79
|
|
|
90
|
-
|
|
80
|
+
Guidelines:
|
|
91
81
|
|
|
92
|
-
|
|
82
|
+
- Keep JSON valid and deterministic.
|
|
83
|
+
- Preserve stable IDs, slugs, and cross-resource references unless intentionally changing them.
|
|
84
|
+
- Update related files together when a resource reference changes.
|
|
85
|
+
- Do not invent unsupported fields. Match the shapes produced by `pnpm pull`.
|
|
86
|
+
- Keep changes small enough to review.
|
|
93
87
|
|
|
94
|
-
|
|
88
|
+
### 3. Validate locally
|
|
95
89
|
|
|
96
|
-
|
|
97
|
-
navigation: [
|
|
98
|
-
// Your custom screens
|
|
99
|
-
{ id: "dashboard", label: "Dashboard", icon: "LayoutDashboard", screen: "custom:dashboard" },
|
|
90
|
+
Run checks that match the change:
|
|
100
91
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
92
|
+
```bash
|
|
93
|
+
pnpm typecheck
|
|
94
|
+
pnpm lint
|
|
95
|
+
pnpm build
|
|
105
96
|
```
|
|
106
97
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
1. Create a screen component in `src/screens/`:
|
|
98
|
+
For visual/content changes, use local preview:
|
|
110
99
|
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
import { TableWidget, TextWidget } from "@fluid-app/portal-sdk";
|
|
114
|
-
|
|
115
|
-
export function OrdersScreen() {
|
|
116
|
-
return (
|
|
117
|
-
<div className="space-y-6">
|
|
118
|
-
<TextWidget title="Orders" titleEnabled padding={4} borderRadius="lg" />
|
|
119
|
-
{/* Add more widgets */}
|
|
120
|
-
</div>
|
|
121
|
-
);
|
|
122
|
-
}
|
|
100
|
+
```bash
|
|
101
|
+
pnpm dev
|
|
123
102
|
```
|
|
124
103
|
|
|
125
|
-
|
|
104
|
+
Expected result: the portal shell starts and can load the local pulled portal definition where supported by the SDK/tooling.
|
|
126
105
|
|
|
127
|
-
|
|
128
|
-
import { OrdersScreen } from "./screens/Orders";
|
|
106
|
+
### 4. Push local definition changes
|
|
129
107
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
orders: OrdersScreen, // Add here
|
|
133
|
-
},
|
|
108
|
+
```bash
|
|
109
|
+
pnpm push
|
|
134
110
|
```
|
|
135
111
|
|
|
136
|
-
|
|
112
|
+
This runs `fluid portal push`, compares local `portal/` JSON against sync state, and updates the remote working/draft definition.
|
|
137
113
|
|
|
138
|
-
|
|
139
|
-
{ id: "orders", label: "Orders", icon: "ShoppingCart", screen: "custom:orders" },
|
|
140
|
-
```
|
|
114
|
+
Push does **not** publish changes live by itself.
|
|
141
115
|
|
|
142
|
-
###
|
|
116
|
+
### 5. Publish a live Fluid OS version
|
|
143
117
|
|
|
144
|
-
|
|
118
|
+
When the pushed working/draft definition is ready for users:
|
|
145
119
|
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
baseUrl: import.meta.env.VITE_API_URL ?? "https://api.fluid.app",
|
|
149
|
-
getAuthToken: () => getStoredToken() ?? null,
|
|
150
|
-
};
|
|
120
|
+
```bash
|
|
121
|
+
pnpm exec fluid portal version create --activate
|
|
151
122
|
```
|
|
152
123
|
|
|
153
|
-
|
|
124
|
+
Only run this when activation is intended. If publishing needs content, design, or release approval, stop and ask first.
|
|
154
125
|
|
|
155
|
-
|
|
126
|
+
## Command boundaries
|
|
156
127
|
|
|
157
|
-
|
|
158
|
-
|--------|-------------|
|
|
159
|
-
| `TextWidget` | Text content with optional title |
|
|
160
|
-
| `ChartWidget` | Bar, line, area, pie charts |
|
|
161
|
-
| `TableWidget` | Data tables with columns |
|
|
162
|
-
| `ListWidget` | Lists with icons and actions |
|
|
163
|
-
| `ToDoWidget` | Task list (uses `useTodos`) |
|
|
164
|
-
| `RecentActivityWidget` | Activity feed (uses `useActivities`) |
|
|
165
|
-
| `CalendarWidget` | Calendar view (uses `useCalendarEvents`) |
|
|
166
|
-
| `CatchUpWidget` | Catch-up items |
|
|
167
|
-
| `AlertWidget` | Info, warning, error alerts |
|
|
168
|
-
| `ImageWidget` | Images with sizing options |
|
|
169
|
-
| `VideoWidget` | Embedded video players |
|
|
170
|
-
| `CarouselWidget` | Image/content carousel |
|
|
171
|
-
| `ContainerWidget` | Layout containers |
|
|
172
|
-
| `SpacerWidget` | Vertical spacing |
|
|
128
|
+
Do not mix these up:
|
|
173
129
|
|
|
174
|
-
|
|
130
|
+
- `fluid portal pull` downloads the remote portal definition into `portal/`.
|
|
131
|
+
- `fluid portal push` syncs local `portal/` JSON to the remote working/draft definition.
|
|
132
|
+
- `fluid portal version create --activate` makes the remote working/draft definition live.
|
|
133
|
+
- `pnpm build` creates hosted shell assets in `dist/`.
|
|
134
|
+
- GitHub Actions deploys hosted shell assets from `dist/`.
|
|
135
|
+
- `fluid portal deploy` publishes company-owned widget runtime artifacts. It does not push portal JSON and does not upload hosted shell assets.
|
|
175
136
|
|
|
176
|
-
|
|
137
|
+
## Widget work
|
|
177
138
|
|
|
178
|
-
|
|
139
|
+
Company-owned portal widgets are supported through the portal widget scaffold:
|
|
179
140
|
|
|
180
141
|
```bash
|
|
181
|
-
pnpm
|
|
142
|
+
pnpm widget:create stock-ticker
|
|
143
|
+
# or
|
|
144
|
+
pnpm exec fluid portal widget create stock-ticker
|
|
182
145
|
```
|
|
183
146
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
type FormData = z.infer<typeof schema>;
|
|
196
|
-
|
|
197
|
-
export function MyFormScreen() {
|
|
198
|
-
const {
|
|
199
|
-
register,
|
|
200
|
-
handleSubmit,
|
|
201
|
-
formState: { errors, isSubmitting },
|
|
202
|
-
} = useZodForm<FormData>(schema);
|
|
203
|
-
|
|
204
|
-
const onSubmit = async (data: FormData) => {
|
|
205
|
-
// Call your API here
|
|
206
|
-
console.log(data);
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
return (
|
|
210
|
-
<form onSubmit={handleSubmit(onSubmit)}>
|
|
211
|
-
<input {...register("name")} placeholder="Name" />
|
|
212
|
-
{errors.name && <p>{errors.name.message}</p>}
|
|
213
|
-
|
|
214
|
-
<input {...register("email")} placeholder="Email" />
|
|
215
|
-
{errors.email && <p>{errors.email.message}</p>}
|
|
216
|
-
|
|
217
|
-
<button type="submit" disabled={isSubmitting}>
|
|
218
|
-
{isSubmitting ? "Submitting..." : "Submit"}
|
|
219
|
-
</button>
|
|
220
|
-
</form>
|
|
221
|
-
);
|
|
222
|
-
}
|
|
223
|
-
```
|
|
147
|
+
The scaffold writes widget source under `src/widgets/<name>/` and wires the widget manifest for portal tooling. Then use the generated widget authoring skill:
|
|
148
|
+
|
|
149
|
+
- `.agents/skills/fluid-widget-authoring/SKILL.md`
|
|
150
|
+
- `.claude/skills/fluid-widget-authoring/SKILL.md`
|
|
151
|
+
|
|
152
|
+
That skill covers widget manifests, property schemas, theme variables, runtime CSS, validation, build, and publish workflows.
|
|
153
|
+
|
|
154
|
+
## Hosted shell deployment
|
|
155
|
+
|
|
156
|
+
The included GitHub Actions workflow builds the portal and uploads `dist/` to Google Cloud Storage plus Cloud CDN.
|
|
224
157
|
|
|
225
|
-
|
|
158
|
+
1. Push to `main` or run the workflow manually.
|
|
159
|
+
2. The workflow runs `pnpm build`.
|
|
160
|
+
3. It syncs `dist/` to `gs://portals-cdn/{{projectName}}/assets/`.
|
|
161
|
+
4. It invalidates the CDN cache for this portal's asset prefix.
|
|
226
162
|
|
|
227
|
-
|
|
163
|
+
Setup:
|
|
228
164
|
|
|
229
|
-
1.
|
|
230
|
-
2.
|
|
165
|
+
1. Create a GCP service account with Storage Object Admin and Compute Load Balancer Admin roles.
|
|
166
|
+
2. Add the service account JSON key as a GitHub Actions secret named `GCP_SA_JSON`.
|
|
167
|
+
3. Set `CDN_HOSTNAME` in `.github/workflows/deploy.yml` to your Cloud CDN load balancer domain.
|
|
168
|
+
4. Update `GCP_PROJECT` and `CDN_URL_MAP` if your project differs from the defaults.
|
|
231
169
|
|
|
232
|
-
##
|
|
170
|
+
## AI authoring kit
|
|
233
171
|
|
|
234
|
-
|
|
172
|
+
Generated projects include portable guidance for AI coding tools:
|
|
235
173
|
|
|
236
|
-
|
|
174
|
+
- `AGENTS.md` — canonical project instructions.
|
|
175
|
+
- `CLAUDE.md` — plain-file bridge to `AGENTS.md`.
|
|
176
|
+
- `.agents/skills/fluid-portal-authoring/SKILL.md` — portal pull/edit/push/version workflow.
|
|
177
|
+
- `.agents/skills/fluid-widget-authoring/SKILL.md` — widget authoring and validation workflow.
|
|
178
|
+
- `.claude/skills/...` — Claude-compatible copies generated from the same template skill files.
|
|
237
179
|
|
|
238
|
-
## Learn
|
|
180
|
+
## Learn more
|
|
239
181
|
|
|
240
|
-
-
|
|
241
|
-
-
|
|
242
|
-
-
|
|
243
|
-
- [React Documentation](https://react.dev)
|
|
182
|
+
- Fluid Commerce Documentation: https://docs.fluidcommerce.com
|
|
183
|
+
- Vite Documentation: https://vite.dev
|
|
184
|
+
- React Documentation: https://react.dev
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Code-defined navigation items.
|
|
3
|
-
*
|
|
4
|
-
* Synced to the Fluid OS API on `fluid deploy` with source: "code".
|
|
5
|
-
* Position is derived from array order. Items without a slug are
|
|
6
|
-
* treated as section headers.
|
|
7
|
-
*
|
|
8
|
-
* User-created navigation items (from the admin dashboard) are not
|
|
9
|
-
* affected — only items with source: "code" are managed.
|
|
10
|
-
*
|
|
11
|
-
* IMPORTANT: Do not add import statements to this file. The Fluid CLI
|
|
12
|
-
* reads this file without resolving dependencies, so it must be
|
|
13
|
-
* self-contained static data only.
|
|
14
|
-
*/
|
|
15
|
-
export const navigation = [
|
|
16
|
-
{
|
|
17
|
-
label: "Dashboard",
|
|
18
|
-
slug: "dashboard",
|
|
19
|
-
icon: "home",
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
label: "MySite",
|
|
23
|
-
slug: "my-site",
|
|
24
|
-
icon: "globe",
|
|
25
|
-
},
|
|
26
|
-
];
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
TextWidget,
|
|
3
|
-
ChartWidget,
|
|
4
|
-
ToDoWidget,
|
|
5
|
-
RecentActivityWidget,
|
|
6
|
-
CalendarWidget,
|
|
7
|
-
} from "@fluid-app/portal-sdk";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Sample chart data extracted as a module-level constant.
|
|
11
|
-
*
|
|
12
|
-
* The data is extracted as a constant to:
|
|
13
|
-
* 1. Keep the component cleaner
|
|
14
|
-
* 2. Allow reuse/testing if needed
|
|
15
|
-
* 3. Make it clear the data is static
|
|
16
|
-
*/
|
|
17
|
-
const MONTHLY_PERFORMANCE_DATA = [
|
|
18
|
-
{ name: "Jan", value: 4000 },
|
|
19
|
-
{ name: "Feb", value: 3000 },
|
|
20
|
-
{ name: "Mar", value: 5000 },
|
|
21
|
-
{ name: "Apr", value: 4500 },
|
|
22
|
-
{ name: "May", value: 6000 },
|
|
23
|
-
{ name: "Jun", value: 5500 },
|
|
24
|
-
];
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Dashboard Screen
|
|
28
|
-
*
|
|
29
|
-
* This is the default landing screen for the portal.
|
|
30
|
-
* It demonstrates using various widgets from portal-sdk:
|
|
31
|
-
*
|
|
32
|
-
* - TextWidget: Display text content with optional title
|
|
33
|
-
* - ToDoWidget: Task list (uses useTodos hook)
|
|
34
|
-
* - RecentActivityWidget: Activity feed (uses useActivities hook)
|
|
35
|
-
* - ChartWidget: Bar, line, area, pie charts
|
|
36
|
-
* - CalendarWidget: Calendar view (uses useCalendarEvents hook)
|
|
37
|
-
*
|
|
38
|
-
* These widgets fetch data from hooks that connect to your Fluid API.
|
|
39
|
-
* In development, they show demo data. Configure fluid.config.ts
|
|
40
|
-
* to connect to your Fluid instance.
|
|
41
|
-
*/
|
|
42
|
-
export function DashboardScreen() {
|
|
43
|
-
return (
|
|
44
|
-
<div className="space-y-6">
|
|
45
|
-
{/* Welcome section */}
|
|
46
|
-
<TextWidget
|
|
47
|
-
titleEnabled
|
|
48
|
-
title="Welcome to Your Portal"
|
|
49
|
-
description="This is your portal dashboard. Use widgets from @fluid-app/portal-sdk to build powerful interfaces for your team."
|
|
50
|
-
padding={4}
|
|
51
|
-
borderRadius="lg"
|
|
52
|
-
/>
|
|
53
|
-
|
|
54
|
-
{/* Stats row - sample static data */}
|
|
55
|
-
<div className="grid gap-6 md:grid-cols-3">
|
|
56
|
-
<div className="bg-background rounded-lg p-4 shadow-sm">
|
|
57
|
-
<p className="text-foreground text-3xl font-bold">$12,450</p>
|
|
58
|
-
<p className="text-muted-foreground mt-1 text-sm">Total Sales</p>
|
|
59
|
-
</div>
|
|
60
|
-
|
|
61
|
-
<div className="bg-background rounded-lg p-4 shadow-sm">
|
|
62
|
-
<p className="text-foreground text-3xl font-bold">24</p>
|
|
63
|
-
<p className="text-muted-foreground mt-1 text-sm">Active Orders</p>
|
|
64
|
-
</div>
|
|
65
|
-
|
|
66
|
-
<div className="bg-background rounded-lg p-4 shadow-sm">
|
|
67
|
-
<p className="text-foreground text-3xl font-bold">156</p>
|
|
68
|
-
<p className="text-muted-foreground mt-1 text-sm">Customers</p>
|
|
69
|
-
</div>
|
|
70
|
-
</div>
|
|
71
|
-
|
|
72
|
-
{/* Main content grid - Tasks and Activity */}
|
|
73
|
-
<div className="grid gap-6 lg:grid-cols-2">
|
|
74
|
-
{/* To-Do Widget - fetches tasks via useTodos hook */}
|
|
75
|
-
<ToDoWidget
|
|
76
|
-
titleEnabled
|
|
77
|
-
titleText="Tasks"
|
|
78
|
-
maxItems={5}
|
|
79
|
-
padding={4}
|
|
80
|
-
borderRadius="lg"
|
|
81
|
-
/>
|
|
82
|
-
|
|
83
|
-
{/* Recent Activity Widget - fetches via useActivities hook */}
|
|
84
|
-
<RecentActivityWidget
|
|
85
|
-
titleEnabled
|
|
86
|
-
titleText="Recent Activity"
|
|
87
|
-
maxItemsToShow={5}
|
|
88
|
-
padding={4}
|
|
89
|
-
borderRadius="lg"
|
|
90
|
-
/>
|
|
91
|
-
</div>
|
|
92
|
-
|
|
93
|
-
{/* Performance chart - uses extracted constant data */}
|
|
94
|
-
<ChartWidget
|
|
95
|
-
titleEnabled
|
|
96
|
-
title="Monthly Performance"
|
|
97
|
-
chartType="bar"
|
|
98
|
-
data={MONTHLY_PERFORMANCE_DATA}
|
|
99
|
-
padding={4}
|
|
100
|
-
borderRadius="lg"
|
|
101
|
-
/>
|
|
102
|
-
|
|
103
|
-
{/* Calendar preview - uses useCalendarEvents hook */}
|
|
104
|
-
<CalendarWidget
|
|
105
|
-
titleEnabled
|
|
106
|
-
titleText="Upcoming Events"
|
|
107
|
-
padding={4}
|
|
108
|
-
borderRadius="lg"
|
|
109
|
-
/>
|
|
110
|
-
|
|
111
|
-
{/* Getting started tips */}
|
|
112
|
-
<div className="grid gap-6 md:grid-cols-2">
|
|
113
|
-
<TextWidget
|
|
114
|
-
titleEnabled
|
|
115
|
-
title="Customize Navigation"
|
|
116
|
-
description="Edit portal.config.ts to add, remove, or reorder navigation items. Core screens (Messaging, Contacts) are built-in."
|
|
117
|
-
padding={4}
|
|
118
|
-
borderRadius="lg"
|
|
119
|
-
background={{ type: "solid", color: "muted" }}
|
|
120
|
-
/>
|
|
121
|
-
|
|
122
|
-
<TextWidget
|
|
123
|
-
titleEnabled
|
|
124
|
-
title="Connect Your Data"
|
|
125
|
-
description="Configure fluid.config.ts with your Fluid API credentials. Widgets will automatically fetch real data from your account."
|
|
126
|
-
padding={4}
|
|
127
|
-
borderRadius="lg"
|
|
128
|
-
background={{ type: "solid", color: "muted" }}
|
|
129
|
-
/>
|
|
130
|
-
</div>
|
|
131
|
-
</div>
|
|
132
|
-
);
|
|
133
|
-
}
|