@cimplify/cli 0.7.10 → 0.7.12
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/{add-SMWNH54I.mjs → add-BCQCRULA.mjs} +1 -1
- package/dist/{chunk-AGJ3GDM5.mjs → chunk-NYRKS2ZC.mjs} +1 -1
- package/dist/chunk-R6TUXVFC.mjs +6463 -0
- package/dist/{chunk-DTKRN5WC.mjs → chunk-ZSO64OIW.mjs} +2 -2
- package/dist/dispatcher.mjs +9 -9
- package/dist/{doctor-DD2HRC43.mjs → doctor-4FTJFRJK.mjs} +2 -2
- package/dist/{explain-H46SCM2M.mjs → explain-6FFAG3OD.mjs} +1 -1
- package/dist/{introspect-YKAWUZ6D.mjs → introspect-2I2MHUMW.mjs} +2 -2
- package/dist/{list-6FF2UPH2.mjs → list-Y7AZYDWJ.mjs} +1 -1
- package/dist/{update-STXI3CS4.mjs → update-SBYEU77K.mjs} +1 -1
- package/package.json +2 -2
- package/templates/storefront-auto/app/account/addresses/actions.ts +56 -0
- package/templates/storefront-auto/app/account/addresses/page.tsx +178 -15
- package/templates/storefront-auto/app/account/orders/page.tsx +84 -15
- package/templates/storefront-auto/app/account/page.tsx +39 -16
- package/templates/storefront-auto/app/account/wallets/actions.ts +52 -0
- package/templates/storefront-auto/app/account/wallets/page.tsx +185 -0
- package/templates/storefront-auto/app/sitemap-page/page.tsx +1 -1
- package/templates/storefront-auto/bun.lock +8 -2
- package/templates/storefront-auto/lib/brand.ts +1 -1
- package/templates/storefront-auto/lib/cimplify-server.ts +54 -0
- package/templates/storefront-auto/middleware.ts +39 -0
- package/templates/storefront-auto/package.json +1 -1
- package/templates/storefront-bakery/AGENTS.md +4 -4
- package/templates/storefront-bakery/app/account/addresses/actions.ts +56 -0
- package/templates/storefront-bakery/app/account/addresses/page.tsx +178 -15
- package/templates/storefront-bakery/app/account/orders/page.tsx +84 -15
- package/templates/storefront-bakery/app/account/page.tsx +39 -16
- package/templates/storefront-bakery/app/account/wallets/actions.ts +52 -0
- package/templates/storefront-bakery/app/account/wallets/page.tsx +185 -0
- package/templates/storefront-bakery/app/sitemap-page/page.tsx +1 -1
- package/templates/storefront-bakery/bun.lock +8 -2
- package/templates/storefront-bakery/lib/brand.ts +1 -1
- package/templates/storefront-bakery/lib/cimplify-server.ts +54 -0
- package/templates/storefront-bakery/middleware.ts +39 -0
- package/templates/storefront-bakery/package.json +1 -1
- package/templates/storefront-fashion/AGENTS.md +4 -4
- package/templates/storefront-fashion/app/account/addresses/actions.ts +56 -0
- package/templates/storefront-fashion/app/account/addresses/page.tsx +178 -15
- package/templates/storefront-fashion/app/account/orders/page.tsx +84 -15
- package/templates/storefront-fashion/app/account/page.tsx +39 -16
- package/templates/storefront-fashion/app/account/wallets/actions.ts +52 -0
- package/templates/storefront-fashion/app/account/wallets/page.tsx +185 -0
- package/templates/storefront-fashion/app/sitemap-page/page.tsx +1 -1
- package/templates/storefront-fashion/bun.lock +8 -2
- package/templates/storefront-fashion/lib/brand.ts +1 -1
- package/templates/storefront-fashion/lib/cimplify-server.ts +54 -0
- package/templates/storefront-fashion/middleware.ts +39 -0
- package/templates/storefront-fashion/package.json +1 -1
- package/templates/storefront-grocery/AGENTS.md +4 -4
- package/templates/storefront-grocery/app/account/addresses/actions.ts +56 -0
- package/templates/storefront-grocery/app/account/addresses/page.tsx +178 -15
- package/templates/storefront-grocery/app/account/orders/page.tsx +84 -15
- package/templates/storefront-grocery/app/account/page.tsx +39 -16
- package/templates/storefront-grocery/app/account/wallets/actions.ts +52 -0
- package/templates/storefront-grocery/app/account/wallets/page.tsx +185 -0
- package/templates/storefront-grocery/app/sitemap-page/page.tsx +1 -1
- package/templates/storefront-grocery/bun.lock +8 -2
- package/templates/storefront-grocery/lib/brand.ts +1 -1
- package/templates/storefront-grocery/lib/cimplify-server.ts +54 -0
- package/templates/storefront-grocery/middleware.ts +39 -0
- package/templates/storefront-grocery/package.json +1 -1
- package/templates/storefront-pharmacy/AGENTS.md +4 -4
- package/templates/storefront-pharmacy/app/account/addresses/actions.ts +56 -0
- package/templates/storefront-pharmacy/app/account/addresses/page.tsx +178 -15
- package/templates/storefront-pharmacy/app/account/orders/page.tsx +84 -15
- package/templates/storefront-pharmacy/app/account/page.tsx +39 -16
- package/templates/storefront-pharmacy/app/account/wallets/actions.ts +52 -0
- package/templates/storefront-pharmacy/app/account/wallets/page.tsx +185 -0
- package/templates/storefront-pharmacy/app/sitemap-page/page.tsx +1 -1
- package/templates/storefront-pharmacy/bun.lock +8 -2
- package/templates/storefront-pharmacy/lib/brand.ts +1 -1
- package/templates/storefront-pharmacy/lib/cimplify-server.ts +54 -0
- package/templates/storefront-pharmacy/middleware.ts +39 -0
- package/templates/storefront-pharmacy/package.json +1 -1
- package/templates/storefront-restaurant/AGENTS.md +4 -4
- package/templates/storefront-restaurant/app/account/addresses/actions.ts +56 -0
- package/templates/storefront-restaurant/app/account/addresses/page.tsx +178 -15
- package/templates/storefront-restaurant/app/account/orders/page.tsx +84 -15
- package/templates/storefront-restaurant/app/account/page.tsx +39 -16
- package/templates/storefront-restaurant/app/account/wallets/actions.ts +52 -0
- package/templates/storefront-restaurant/app/account/wallets/page.tsx +185 -0
- package/templates/storefront-restaurant/app/sitemap-page/page.tsx +1 -1
- package/templates/storefront-restaurant/bun.lock +8 -2
- package/templates/storefront-restaurant/lib/brand.ts +1 -1
- package/templates/storefront-restaurant/lib/cimplify-server.ts +54 -0
- package/templates/storefront-restaurant/middleware.ts +39 -0
- package/templates/storefront-restaurant/package.json +1 -1
- package/templates/storefront-retail/AGENTS.md +4 -4
- package/templates/storefront-retail/app/account/addresses/actions.ts +56 -0
- package/templates/storefront-retail/app/account/addresses/page.tsx +178 -15
- package/templates/storefront-retail/app/account/orders/page.tsx +84 -15
- package/templates/storefront-retail/app/account/page.tsx +39 -16
- package/templates/storefront-retail/app/account/wallets/actions.ts +52 -0
- package/templates/storefront-retail/app/account/wallets/page.tsx +185 -0
- package/templates/storefront-retail/app/sitemap-page/page.tsx +1 -1
- package/templates/storefront-retail/bun.lock +8 -2
- package/templates/storefront-retail/lib/brand.ts +1 -1
- package/templates/storefront-retail/lib/cimplify-server.ts +54 -0
- package/templates/storefront-retail/middleware.ts +39 -0
- package/templates/storefront-retail/package.json +1 -1
- package/templates/storefront-services/AGENTS.md +4 -4
- package/templates/storefront-services/app/account/addresses/actions.ts +56 -0
- package/templates/storefront-services/app/account/addresses/page.tsx +178 -15
- package/templates/storefront-services/app/account/orders/page.tsx +84 -15
- package/templates/storefront-services/app/account/page.tsx +39 -16
- package/templates/storefront-services/app/account/wallets/actions.ts +52 -0
- package/templates/storefront-services/app/account/wallets/page.tsx +185 -0
- package/templates/storefront-services/app/sitemap-page/page.tsx +1 -1
- package/templates/storefront-services/bun.lock +8 -2
- package/templates/storefront-services/lib/brand.ts +1 -1
- package/templates/storefront-services/lib/cimplify-server.ts +54 -0
- package/templates/storefront-services/middleware.ts +39 -0
- package/templates/storefront-services/package.json +1 -1
- package/dist/chunk-YFLBC6BL.mjs +0 -6151
- package/templates/storefront-auto/app/account/settings/page.tsx +0 -21
- package/templates/storefront-auto/components/account-iframe.tsx +0 -19
- package/templates/storefront-bakery/app/account/settings/page.tsx +0 -21
- package/templates/storefront-bakery/components/account-iframe.tsx +0 -19
- package/templates/storefront-fashion/app/account/settings/page.tsx +0 -21
- package/templates/storefront-fashion/components/account-iframe.tsx +0 -19
- package/templates/storefront-grocery/app/account/settings/page.tsx +0 -21
- package/templates/storefront-grocery/components/account-iframe.tsx +0 -19
- package/templates/storefront-pharmacy/app/account/settings/page.tsx +0 -21
- package/templates/storefront-pharmacy/components/account-iframe.tsx +0 -19
- package/templates/storefront-restaurant/app/account/settings/page.tsx +0 -21
- package/templates/storefront-restaurant/components/account-iframe.tsx +0 -19
- package/templates/storefront-retail/app/account/settings/page.tsx +0 -21
- package/templates/storefront-retail/components/account-iframe.tsx +0 -19
- package/templates/storefront-services/app/account/settings/page.tsx +0 -21
- package/templates/storefront-services/components/account-iframe.tsx +0 -19
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// package.json
|
|
3
3
|
var package_default = {
|
|
4
4
|
name: "@cimplify/cli",
|
|
5
|
-
version: "0.7.
|
|
5
|
+
version: "0.7.12",
|
|
6
6
|
description: "Cimplify CLI \u2014 deploy, manage env vars, link projects, and scaffold storefronts",
|
|
7
7
|
keywords: [
|
|
8
8
|
"cimplify",
|
|
@@ -47,7 +47,7 @@ var package_default = {
|
|
|
47
47
|
vitest: "^4.1.5"
|
|
48
48
|
},
|
|
49
49
|
dependencies: {
|
|
50
|
-
"@cimplify/sdk": "^0.
|
|
50
|
+
"@cimplify/sdk": "^0.67.0"
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
53
|
|
package/dist/dispatcher.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { TEMPLATES } from './chunk-
|
|
3
|
-
import { package_default } from './chunk-
|
|
2
|
+
import { TEMPLATES } from './chunk-R6TUXVFC.mjs';
|
|
3
|
+
import { package_default } from './chunk-ZSO64OIW.mjs';
|
|
4
4
|
|
|
5
5
|
// src/dispatcher.ts
|
|
6
6
|
var VERSION = package_default.version ?? "unknown";
|
|
@@ -138,16 +138,16 @@ var COMMANDS = {
|
|
|
138
138
|
logs: () => import('./logs-YNN2PQ24.mjs'),
|
|
139
139
|
status: () => import('./status-JSYXM5RT.mjs'),
|
|
140
140
|
dev: () => import('./dev-ONW2S77K.mjs'),
|
|
141
|
-
introspect: () => import('./introspect-
|
|
141
|
+
introspect: () => import('./introspect-2I2MHUMW.mjs'),
|
|
142
142
|
inspect: () => import('./inspect-CGYX4DDF.mjs'),
|
|
143
|
-
doctor: () => import('./doctor-
|
|
144
|
-
explain: () => import('./explain-
|
|
143
|
+
doctor: () => import('./doctor-4FTJFRJK.mjs'),
|
|
144
|
+
explain: () => import('./explain-6FFAG3OD.mjs'),
|
|
145
145
|
assets: () => import('./assets-74SK63TR.mjs'),
|
|
146
146
|
repo: () => import('./repo-KNQMSPVV.mjs'),
|
|
147
|
-
list: () => import('./list-
|
|
148
|
-
add: () => import('./add-
|
|
149
|
-
update: () => import('./update-
|
|
150
|
-
upgrade: () => import('./update-
|
|
147
|
+
list: () => import('./list-Y7AZYDWJ.mjs'),
|
|
148
|
+
add: () => import('./add-BCQCRULA.mjs'),
|
|
149
|
+
update: () => import('./update-SBYEU77K.mjs'),
|
|
150
|
+
upgrade: () => import('./update-SBYEU77K.mjs'),
|
|
151
151
|
"auth-step-up": () => import('./auth-step-up-BIUYQJP6.mjs')
|
|
152
152
|
};
|
|
153
153
|
var COMMAND_PREFIXES = {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { gatherIntrospection } from './chunk-
|
|
2
|
+
import { gatherIntrospection } from './chunk-NYRKS2ZC.mjs';
|
|
3
3
|
import './chunk-K5464A3L.mjs';
|
|
4
4
|
import './chunk-DBZ3UOQ2.mjs';
|
|
5
|
-
import './chunk-
|
|
5
|
+
import './chunk-ZSO64OIW.mjs';
|
|
6
6
|
import { parseArgs, flagBool } from './chunk-C4M3DXKC.mjs';
|
|
7
7
|
import { ApiClient } from './chunk-MAOO6ZZ5.mjs';
|
|
8
8
|
import { readAuthOrNull } from './chunk-UBAI443T.mjs';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { package_default } from './chunk-
|
|
2
|
+
import { package_default } from './chunk-ZSO64OIW.mjs';
|
|
3
3
|
import { parseArgs } from './chunk-C4M3DXKC.mjs';
|
|
4
4
|
import { bold, dim, info, result, CliError, CLI_ERROR_CODE } from './chunk-E2T2SBP5.mjs';
|
|
5
5
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
export { run as default, extractMockSeed, gatherIntrospection, renderIntrospection } from './chunk-
|
|
2
|
+
export { run as default, extractMockSeed, gatherIntrospection, renderIntrospection } from './chunk-NYRKS2ZC.mjs';
|
|
3
3
|
import './chunk-K5464A3L.mjs';
|
|
4
4
|
import './chunk-DBZ3UOQ2.mjs';
|
|
5
|
-
import './chunk-
|
|
5
|
+
import './chunk-ZSO64OIW.mjs';
|
|
6
6
|
import './chunk-C4M3DXKC.mjs';
|
|
7
7
|
import './chunk-UBAI443T.mjs';
|
|
8
8
|
import './chunk-E2T2SBP5.mjs';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { REGISTRY_INDEX } from './chunk-
|
|
2
|
+
import { REGISTRY_INDEX } from './chunk-R6TUXVFC.mjs';
|
|
3
3
|
import { parseArgs, flagBool } from './chunk-C4M3DXKC.mjs';
|
|
4
4
|
import { CliError, CLI_ERROR_CODE, info, bold, dim, green, result } from './chunk-E2T2SBP5.mjs';
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { package_default } from './chunk-
|
|
2
|
+
import { package_default } from './chunk-ZSO64OIW.mjs';
|
|
3
3
|
import { promptYesNo } from './chunk-ITAFAORS.mjs';
|
|
4
4
|
import { parseArgs, flagBool, flagString } from './chunk-C4M3DXKC.mjs';
|
|
5
5
|
import { success, bold, info, dim, result, failure, CliError, CLI_ERROR_CODE, step, isJsonMode } from './chunk-E2T2SBP5.mjs';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cimplify/cli",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.12",
|
|
4
4
|
"description": "Cimplify CLI — deploy, manage env vars, link projects, and scaffold storefronts",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cimplify",
|
|
@@ -45,6 +45,6 @@
|
|
|
45
45
|
"vitest": "^4.1.5"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@cimplify/sdk": "^0.
|
|
48
|
+
"@cimplify/sdk": "^0.67.0"
|
|
49
49
|
}
|
|
50
50
|
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
|
|
3
|
+
import { revalidatePath } from "next/cache";
|
|
4
|
+
import { apiFetch, serverAccessToken } from "@/lib/cimplify-server";
|
|
5
|
+
import type { CustomerAddress } from "@cimplify/sdk";
|
|
6
|
+
|
|
7
|
+
const ACCOUNT_ADDRESSES = "/account/addresses";
|
|
8
|
+
|
|
9
|
+
function required(form: FormData, key: string): string {
|
|
10
|
+
const value = String(form.get(key) ?? "").trim();
|
|
11
|
+
if (!value) throw new Error(`Missing required field: ${key}`);
|
|
12
|
+
return value;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function optional(form: FormData, key: string): string | undefined {
|
|
16
|
+
const value = String(form.get(key) ?? "").trim();
|
|
17
|
+
return value || undefined;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export async function createAddressAction(form: FormData): Promise<void> {
|
|
21
|
+
const bearer = await serverAccessToken();
|
|
22
|
+
await apiFetch<CustomerAddress>("/v1/link/addresses", {
|
|
23
|
+
bearer,
|
|
24
|
+
method: "POST",
|
|
25
|
+
body: JSON.stringify({
|
|
26
|
+
label: optional(form, "label"),
|
|
27
|
+
street_address: required(form, "street_address"),
|
|
28
|
+
apartment: optional(form, "apartment"),
|
|
29
|
+
city: required(form, "city"),
|
|
30
|
+
region: optional(form, "region"),
|
|
31
|
+
postal_code: optional(form, "postal_code"),
|
|
32
|
+
country: optional(form, "country"),
|
|
33
|
+
}),
|
|
34
|
+
});
|
|
35
|
+
revalidatePath(ACCOUNT_ADDRESSES);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export async function deleteAddressAction(form: FormData): Promise<void> {
|
|
39
|
+
const bearer = await serverAccessToken();
|
|
40
|
+
const id = required(form, "address_id");
|
|
41
|
+
await apiFetch<unknown>(`/v1/link/addresses/${encodeURIComponent(id)}`, {
|
|
42
|
+
bearer,
|
|
43
|
+
method: "DELETE",
|
|
44
|
+
});
|
|
45
|
+
revalidatePath(ACCOUNT_ADDRESSES);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export async function setDefaultAddressAction(form: FormData): Promise<void> {
|
|
49
|
+
const bearer = await serverAccessToken();
|
|
50
|
+
const id = required(form, "address_id");
|
|
51
|
+
await apiFetch<unknown>(`/v1/link/addresses/${encodeURIComponent(id)}/default`, {
|
|
52
|
+
bearer,
|
|
53
|
+
method: "POST",
|
|
54
|
+
});
|
|
55
|
+
revalidatePath(ACCOUNT_ADDRESSES);
|
|
56
|
+
}
|
|
@@ -1,21 +1,184 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
AccountContent,
|
|
3
|
+
AccountHero,
|
|
4
|
+
AccountNav,
|
|
5
|
+
AccountShell,
|
|
6
|
+
AccountSidebar,
|
|
7
|
+
AccountSignedOutPrompt,
|
|
8
|
+
Button,
|
|
9
|
+
EmptyState,
|
|
10
|
+
Section,
|
|
11
|
+
} from "@cimplify/sdk/react";
|
|
12
|
+
import type { CustomerAddress } from "@cimplify/sdk";
|
|
3
13
|
import { brand } from "@/lib/brand";
|
|
14
|
+
import { ACCOUNT_NAV, apiFetch, serverAccessToken, serverSession } from "@/lib/cimplify-server";
|
|
15
|
+
import {
|
|
16
|
+
createAddressAction,
|
|
17
|
+
deleteAddressAction,
|
|
18
|
+
setDefaultAddressAction,
|
|
19
|
+
} from "./actions";
|
|
4
20
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
21
|
+
const CLIENT_ID = process.env.NEXT_PUBLIC_CIMPLIFY_CLIENT_ID ?? "";
|
|
22
|
+
const REDIRECT_URI = process.env.CIMPLIFY_REDIRECT_URI ?? "";
|
|
23
|
+
|
|
24
|
+
function singleLine(address: CustomerAddress): string {
|
|
25
|
+
return [
|
|
26
|
+
address.street_address,
|
|
27
|
+
address.apartment,
|
|
28
|
+
address.city,
|
|
29
|
+
address.region,
|
|
30
|
+
address.postal_code,
|
|
31
|
+
address.country,
|
|
32
|
+
]
|
|
33
|
+
.filter(Boolean)
|
|
34
|
+
.join(", ");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function AddressCard({ address }: { address: CustomerAddress }) {
|
|
38
|
+
const isDefault = address.is_default === true;
|
|
39
|
+
return (
|
|
40
|
+
<div className="flex items-start justify-between gap-4 rounded-[14px] border border-border bg-card p-5">
|
|
41
|
+
<div className="min-w-0">
|
|
42
|
+
<div className="flex items-center gap-2 mb-1.5">
|
|
43
|
+
<span className="text-[14px] font-medium text-foreground">{address.label || "Address"}</span>
|
|
44
|
+
{isDefault && (
|
|
45
|
+
<span className="text-[10px] font-medium tracking-[0.08em] uppercase text-foreground/60 bg-foreground/5 px-2 py-0.5 rounded-full">
|
|
46
|
+
Default
|
|
47
|
+
</span>
|
|
48
|
+
)}
|
|
49
|
+
</div>
|
|
50
|
+
<p className="text-[13px] text-foreground/70 leading-relaxed truncate">
|
|
51
|
+
{singleLine(address)}
|
|
52
|
+
</p>
|
|
53
|
+
</div>
|
|
54
|
+
<div className="flex items-center gap-2 shrink-0">
|
|
55
|
+
{!isDefault && (
|
|
56
|
+
<form action={setDefaultAddressAction}>
|
|
57
|
+
<input type="hidden" name="address_id" value={address.id} />
|
|
58
|
+
<button
|
|
59
|
+
type="submit"
|
|
60
|
+
className="text-[12px] font-medium text-foreground/70 hover:text-foreground px-2 py-1"
|
|
61
|
+
>
|
|
62
|
+
Make default
|
|
63
|
+
</button>
|
|
64
|
+
</form>
|
|
65
|
+
)}
|
|
66
|
+
<form action={deleteAddressAction}>
|
|
67
|
+
<input type="hidden" name="address_id" value={address.id} />
|
|
68
|
+
<button
|
|
69
|
+
type="submit"
|
|
70
|
+
className="text-[12px] font-medium text-destructive/80 hover:text-destructive px-2 py-1"
|
|
71
|
+
>
|
|
72
|
+
Remove
|
|
73
|
+
</button>
|
|
74
|
+
</form>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function AddAddressForm() {
|
|
81
|
+
return (
|
|
82
|
+
<form
|
|
83
|
+
action={createAddressAction}
|
|
84
|
+
className="rounded-[14px] border border-dashed border-border bg-card p-5 space-y-3"
|
|
85
|
+
>
|
|
86
|
+
<h3 className="text-[13px] font-semibold tracking-[0.02em] text-foreground">Add an address</h3>
|
|
87
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
|
88
|
+
<input
|
|
89
|
+
name="label"
|
|
90
|
+
placeholder="Label (Home, Work)"
|
|
91
|
+
className="rounded-[10px] border border-border bg-background px-3 h-10 text-[13px]"
|
|
92
|
+
/>
|
|
93
|
+
<input
|
|
94
|
+
name="street_address"
|
|
95
|
+
required
|
|
96
|
+
placeholder="Street address"
|
|
97
|
+
className="rounded-[10px] border border-border bg-background px-3 h-10 text-[13px]"
|
|
98
|
+
/>
|
|
99
|
+
<input
|
|
100
|
+
name="apartment"
|
|
101
|
+
placeholder="Apartment / unit (optional)"
|
|
102
|
+
className="rounded-[10px] border border-border bg-background px-3 h-10 text-[13px]"
|
|
103
|
+
/>
|
|
104
|
+
<input
|
|
105
|
+
name="city"
|
|
106
|
+
required
|
|
107
|
+
placeholder="City"
|
|
108
|
+
className="rounded-[10px] border border-border bg-background px-3 h-10 text-[13px]"
|
|
109
|
+
/>
|
|
110
|
+
<input
|
|
111
|
+
name="region"
|
|
112
|
+
placeholder="Region / state"
|
|
113
|
+
className="rounded-[10px] border border-border bg-background px-3 h-10 text-[13px]"
|
|
114
|
+
/>
|
|
115
|
+
<input
|
|
116
|
+
name="postal_code"
|
|
117
|
+
placeholder="Postal code"
|
|
118
|
+
className="rounded-[10px] border border-border bg-background px-3 h-10 text-[13px]"
|
|
119
|
+
/>
|
|
120
|
+
</div>
|
|
121
|
+
<input
|
|
122
|
+
name="country"
|
|
123
|
+
placeholder="Country"
|
|
124
|
+
className="rounded-[10px] border border-border bg-background px-3 h-10 text-[13px] w-full"
|
|
125
|
+
/>
|
|
126
|
+
<div className="flex justify-end">
|
|
127
|
+
<Button type="submit" variant="primary">
|
|
128
|
+
Save address
|
|
129
|
+
</Button>
|
|
130
|
+
</div>
|
|
131
|
+
</form>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export default async function AddressesPage() {
|
|
136
|
+
const session = await serverSession();
|
|
137
|
+
if (!session) {
|
|
138
|
+
return (
|
|
139
|
+
<AccountSignedOutPrompt
|
|
140
|
+
clientId={CLIENT_ID}
|
|
141
|
+
redirectUri={REDIRECT_URI}
|
|
142
|
+
eyebrow={brand.account.loginEyebrow}
|
|
143
|
+
title={brand.account.loginTitle}
|
|
144
|
+
description={brand.account.loginSubtitle}
|
|
145
|
+
/>
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const bearer = await serverAccessToken();
|
|
150
|
+
const addresses = (await apiFetch<CustomerAddress[]>("/v1/link/addresses", { bearer })) ?? [];
|
|
8
151
|
|
|
9
|
-
export default function AddressesPage() {
|
|
10
152
|
return (
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
<
|
|
19
|
-
|
|
153
|
+
<AccountShell
|
|
154
|
+
sidebar={
|
|
155
|
+
<AccountSidebar>
|
|
156
|
+
<AccountNav items={ACCOUNT_NAV} activeHref="/account/addresses" />
|
|
157
|
+
</AccountSidebar>
|
|
158
|
+
}
|
|
159
|
+
>
|
|
160
|
+
<AccountHero
|
|
161
|
+
eyebrow="Saved addresses"
|
|
162
|
+
title="Where should we deliver?"
|
|
163
|
+
subtitle="Saved addresses sync across every Cimplify shop you use."
|
|
164
|
+
/>
|
|
165
|
+
<AccountContent>
|
|
166
|
+
<Section title="Your addresses" meta={`${addresses.length} saved`}>
|
|
167
|
+
<div className="space-y-3">
|
|
168
|
+
{addresses.length === 0 ? (
|
|
169
|
+
<EmptyState
|
|
170
|
+
title="No addresses yet"
|
|
171
|
+
description="Add a delivery address to check out faster next time."
|
|
172
|
+
/>
|
|
173
|
+
) : (
|
|
174
|
+
addresses.map((address) => <AddressCard key={address.id} address={address} />)
|
|
175
|
+
)}
|
|
176
|
+
</div>
|
|
177
|
+
</Section>
|
|
178
|
+
<Section title="Add another">
|
|
179
|
+
<AddAddressForm />
|
|
180
|
+
</Section>
|
|
181
|
+
</AccountContent>
|
|
182
|
+
</AccountShell>
|
|
20
183
|
);
|
|
21
184
|
}
|
|
@@ -1,21 +1,90 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
AccountOrdersPage,
|
|
3
|
+
AccountSignedOutPrompt,
|
|
4
|
+
} from "@cimplify/sdk/react";
|
|
5
|
+
import type { OrderRowData, OrderRowStatus } from "@cimplify/sdk/react";
|
|
6
|
+
import type { Order, OrderStatus } from "@cimplify/sdk";
|
|
7
|
+
import { formatMoney } from "@cimplify/sdk";
|
|
3
8
|
import { brand } from "@/lib/brand";
|
|
9
|
+
import { ACCOUNT_NAV, apiFetch, serverAccessToken, serverSession } from "@/lib/cimplify-server";
|
|
4
10
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
11
|
+
const CLIENT_ID = process.env.NEXT_PUBLIC_CIMPLIFY_CLIENT_ID ?? "";
|
|
12
|
+
const REDIRECT_URI = process.env.CIMPLIFY_REDIRECT_URI ?? "";
|
|
13
|
+
|
|
14
|
+
function mapStatus(status: OrderStatus): OrderRowStatus {
|
|
15
|
+
switch (status) {
|
|
16
|
+
case "in_preparation":
|
|
17
|
+
case "ready_to_serve":
|
|
18
|
+
case "partially_served":
|
|
19
|
+
return { kind: "preparing", label: "Preparing" };
|
|
20
|
+
case "delivered":
|
|
21
|
+
return { kind: "delivered" };
|
|
22
|
+
case "picked_up":
|
|
23
|
+
return { kind: "delivered", label: "Picked up" };
|
|
24
|
+
case "served":
|
|
25
|
+
case "completed":
|
|
26
|
+
return { kind: "completed" };
|
|
27
|
+
case "cancelled":
|
|
28
|
+
case "refunded":
|
|
29
|
+
return { kind: "cancelled", label: status === "refunded" ? "Refunded" : undefined };
|
|
30
|
+
case "pending":
|
|
31
|
+
case "created":
|
|
32
|
+
case "confirmed":
|
|
33
|
+
default:
|
|
34
|
+
return { kind: "active", label: "Confirmed" };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function relativeMeta(iso: string, orderNumber: string): string {
|
|
39
|
+
const when = new Date(iso);
|
|
40
|
+
const formatted = when.toLocaleDateString(undefined, {
|
|
41
|
+
month: "short",
|
|
42
|
+
day: "numeric",
|
|
43
|
+
year: when.getFullYear() === new Date().getFullYear() ? undefined : "numeric",
|
|
44
|
+
});
|
|
45
|
+
return `Order ${orderNumber} · ${formatted}`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function toRowData(order: Order): OrderRowData {
|
|
49
|
+
const count = order.items?.length ?? 0;
|
|
50
|
+
return {
|
|
51
|
+
id: order.id,
|
|
52
|
+
href: `/account/orders/${order.id}`,
|
|
53
|
+
summary: count > 0 ? `${count} ${count === 1 ? "item" : "items"}` : "Order",
|
|
54
|
+
meta: relativeMeta(order.created_at, order.user_friendly_id ?? order.id),
|
|
55
|
+
status: mapStatus(order.status),
|
|
56
|
+
total: formatMoney(order.total_price, order.currency),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export default async function OrdersPage() {
|
|
61
|
+
const session = await serverSession();
|
|
62
|
+
if (!session) {
|
|
63
|
+
return (
|
|
64
|
+
<AccountSignedOutPrompt
|
|
65
|
+
clientId={CLIENT_ID}
|
|
66
|
+
redirectUri={REDIRECT_URI}
|
|
67
|
+
eyebrow={brand.account.loginEyebrow}
|
|
68
|
+
title={brand.account.loginTitle}
|
|
69
|
+
description={brand.account.loginSubtitle}
|
|
70
|
+
/>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const bearer = await serverAccessToken();
|
|
75
|
+
const orders = await apiFetch<Order[]>(
|
|
76
|
+
`/v1/link/orders?business_id=${encodeURIComponent(brand.mock.businessId)}`,
|
|
77
|
+
{ bearer },
|
|
78
|
+
);
|
|
8
79
|
|
|
9
|
-
export default function OrdersPage() {
|
|
10
80
|
return (
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
</article>
|
|
81
|
+
<AccountOrdersPage
|
|
82
|
+
customerName={session.name ?? ""}
|
|
83
|
+
customerEmail={session.email}
|
|
84
|
+
customerId={session.sub}
|
|
85
|
+
merchantName={brand.name}
|
|
86
|
+
nav={ACCOUNT_NAV}
|
|
87
|
+
orders={(orders ?? []).map(toRowData)}
|
|
88
|
+
/>
|
|
20
89
|
);
|
|
21
90
|
}
|
|
@@ -1,22 +1,45 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
AccountDashboardPage,
|
|
3
|
+
AccountSignedOutPrompt,
|
|
4
|
+
} from "@cimplify/sdk/react";
|
|
5
|
+
import type { CustomerAddress, CustomerMobileMoney } from "@cimplify/sdk";
|
|
3
6
|
import { brand } from "@/lib/brand";
|
|
7
|
+
import { ACCOUNT_NAV, apiFetch, serverAccessToken, serverSession } from "@/lib/cimplify-server";
|
|
4
8
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
const CLIENT_ID = process.env.NEXT_PUBLIC_CIMPLIFY_CLIENT_ID ?? "";
|
|
10
|
+
const REDIRECT_URI = process.env.CIMPLIFY_REDIRECT_URI ?? "";
|
|
11
|
+
|
|
12
|
+
export default async function AccountPage() {
|
|
13
|
+
const session = await serverSession();
|
|
14
|
+
if (!session) {
|
|
15
|
+
return (
|
|
16
|
+
<AccountSignedOutPrompt
|
|
17
|
+
clientId={CLIENT_ID}
|
|
18
|
+
redirectUri={REDIRECT_URI}
|
|
19
|
+
eyebrow={brand.account.loginEyebrow}
|
|
20
|
+
title={brand.account.loginTitle}
|
|
21
|
+
description={brand.account.loginSubtitle}
|
|
22
|
+
/>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const bearer = await serverAccessToken();
|
|
27
|
+
const [addresses, wallets] = await Promise.all([
|
|
28
|
+
apiFetch<CustomerAddress[]>("/v1/link/addresses", { bearer }),
|
|
29
|
+
apiFetch<CustomerMobileMoney[]>("/v1/link/mobile-money", { bearer }),
|
|
30
|
+
]);
|
|
9
31
|
|
|
10
|
-
export default function AccountPage() {
|
|
11
32
|
return (
|
|
12
|
-
<
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
33
|
+
<AccountDashboardPage
|
|
34
|
+
customerName={session.name ?? ""}
|
|
35
|
+
customerEmail={session.email}
|
|
36
|
+
customerId={session.sub}
|
|
37
|
+
merchantName={brand.name}
|
|
38
|
+
nav={ACCOUNT_NAV}
|
|
39
|
+
identitySummary={{
|
|
40
|
+
addresses: addresses?.length ?? 0,
|
|
41
|
+
paymentMethods: wallets?.length ?? 0,
|
|
42
|
+
}}
|
|
43
|
+
/>
|
|
21
44
|
);
|
|
22
45
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
|
|
3
|
+
import { revalidatePath } from "next/cache";
|
|
4
|
+
import { apiFetch, serverAccessToken } from "@/lib/cimplify-server";
|
|
5
|
+
import type { CustomerMobileMoney, MobileMoneyProvider } from "@cimplify/sdk";
|
|
6
|
+
|
|
7
|
+
const ACCOUNT_WALLETS = "/account/wallets";
|
|
8
|
+
|
|
9
|
+
function required(form: FormData, key: string): string {
|
|
10
|
+
const value = String(form.get(key) ?? "").trim();
|
|
11
|
+
if (!value) throw new Error(`Missing required field: ${key}`);
|
|
12
|
+
return value;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function optional(form: FormData, key: string): string | undefined {
|
|
16
|
+
const value = String(form.get(key) ?? "").trim();
|
|
17
|
+
return value || undefined;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export async function createWalletAction(form: FormData): Promise<void> {
|
|
21
|
+
const bearer = await serverAccessToken();
|
|
22
|
+
await apiFetch<CustomerMobileMoney>("/v1/link/mobile-money", {
|
|
23
|
+
bearer,
|
|
24
|
+
method: "POST",
|
|
25
|
+
body: JSON.stringify({
|
|
26
|
+
phone_number: required(form, "phone_number"),
|
|
27
|
+
provider: required(form, "provider") as MobileMoneyProvider,
|
|
28
|
+
label: optional(form, "label"),
|
|
29
|
+
}),
|
|
30
|
+
});
|
|
31
|
+
revalidatePath(ACCOUNT_WALLETS);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export async function deleteWalletAction(form: FormData): Promise<void> {
|
|
35
|
+
const bearer = await serverAccessToken();
|
|
36
|
+
const id = required(form, "mobile_money_id");
|
|
37
|
+
await apiFetch<unknown>(`/v1/link/mobile-money/${encodeURIComponent(id)}`, {
|
|
38
|
+
bearer,
|
|
39
|
+
method: "DELETE",
|
|
40
|
+
});
|
|
41
|
+
revalidatePath(ACCOUNT_WALLETS);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export async function setDefaultWalletAction(form: FormData): Promise<void> {
|
|
45
|
+
const bearer = await serverAccessToken();
|
|
46
|
+
const id = required(form, "mobile_money_id");
|
|
47
|
+
await apiFetch<unknown>(`/v1/link/mobile-money/${encodeURIComponent(id)}/default`, {
|
|
48
|
+
bearer,
|
|
49
|
+
method: "POST",
|
|
50
|
+
});
|
|
51
|
+
revalidatePath(ACCOUNT_WALLETS);
|
|
52
|
+
}
|