@doswiftly/cli 0.1.19 → 0.1.20
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/commands/deploy.d.ts +20 -0
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +219 -6
- package/dist/commands/deploy.js.map +1 -1
- package/package.json +4 -4
- package/templates/storefront-minimal/.github/workflows/build-template.yml +10 -0
- package/templates/storefront-minimal/wrangler.toml +11 -0
- package/templates/storefront-nextjs/.github/workflows/build-template.yml +10 -0
- package/templates/storefront-nextjs/wrangler.toml +11 -0
- package/templates/storefront-nextjs-shadcn/.github/workflows/build-template.yml +10 -0
- package/templates/storefront-nextjs-shadcn/CLAUDE.md +29 -5
- package/templates/storefront-nextjs-shadcn/app/{about → [locale]/about}/page.tsx +17 -14
- package/templates/storefront-nextjs-shadcn/app/{account → [locale]/account}/addresses/page.tsx +19 -15
- package/templates/storefront-nextjs-shadcn/app/{account → [locale]/account}/error.tsx +8 -5
- package/templates/storefront-nextjs-shadcn/app/{account → [locale]/account}/loyalty/page.tsx +39 -34
- package/templates/storefront-nextjs-shadcn/app/{account → [locale]/account}/orders/[id]/page.tsx +9 -7
- package/templates/storefront-nextjs-shadcn/app/{account → [locale]/account}/orders/[id]/tracking/page.tsx +27 -25
- package/templates/storefront-nextjs-shadcn/app/{account → [locale]/account}/orders/page.tsx +13 -9
- package/templates/storefront-nextjs-shadcn/app/{account → [locale]/account}/page.tsx +1 -2
- package/templates/storefront-nextjs-shadcn/app/{account → [locale]/account}/settings/page.tsx +1 -1
- package/templates/storefront-nextjs-shadcn/app/{auth → [locale]/auth}/forgot-password/page.tsx +14 -12
- package/templates/storefront-nextjs-shadcn/app/{auth → [locale]/auth}/login/page.tsx +5 -2
- package/templates/storefront-nextjs-shadcn/app/{auth → [locale]/auth}/register/page.tsx +5 -2
- package/templates/storefront-nextjs-shadcn/app/{blog → [locale]/blog}/[slug]/page.tsx +1 -1
- package/templates/storefront-nextjs-shadcn/app/{cart → [locale]/cart}/page.tsx +14 -10
- package/templates/storefront-nextjs-shadcn/app/{categories → [locale]/categories}/[slug]/category-products-client.tsx +4 -2
- package/templates/storefront-nextjs-shadcn/app/{categories → [locale]/categories}/page.tsx +13 -8
- package/templates/storefront-nextjs-shadcn/app/{checkout → [locale]/checkout}/error.tsx +1 -1
- package/templates/storefront-nextjs-shadcn/app/{checkout → [locale]/checkout}/page.tsx +228 -184
- package/templates/storefront-nextjs-shadcn/app/{checkout → [locale]/checkout}/success/[orderId]/page.tsx +36 -34
- package/templates/storefront-nextjs-shadcn/app/{collections → [locale]/collections}/[handle]/page.tsx +5 -3
- package/templates/storefront-nextjs-shadcn/app/{collections → [locale]/collections}/page.tsx +13 -8
- package/templates/storefront-nextjs-shadcn/app/{contact → [locale]/contact}/page.tsx +24 -21
- package/templates/storefront-nextjs-shadcn/app/{error.tsx → [locale]/error.tsx} +13 -8
- package/templates/storefront-nextjs-shadcn/app/[locale]/layout.tsx +92 -0
- package/templates/storefront-nextjs-shadcn/app/{not-found.tsx → [locale]/not-found.tsx} +13 -18
- package/templates/storefront-nextjs-shadcn/app/{page.tsx → [locale]/page.tsx} +8 -4
- package/templates/storefront-nextjs-shadcn/app/{products → [locale]/products}/[slug]/error.tsx +1 -1
- package/templates/storefront-nextjs-shadcn/app/{products → [locale]/products}/[slug]/page.tsx +11 -8
- package/templates/storefront-nextjs-shadcn/app/{products → [locale]/products}/[slug]/product-client.tsx +3 -1
- package/templates/storefront-nextjs-shadcn/app/{products → [locale]/products}/page.tsx +6 -3
- package/templates/storefront-nextjs-shadcn/app/{products → [locale]/products}/products-client.tsx +14 -10
- package/templates/storefront-nextjs-shadcn/app/{wishlist → [locale]/wishlist}/page.tsx +21 -25
- package/templates/storefront-nextjs-shadcn/app/layout.tsx +6 -68
- package/templates/storefront-nextjs-shadcn/components/account/address-form.tsx +25 -20
- package/templates/storefront-nextjs-shadcn/components/account/address-list.tsx +11 -10
- package/templates/storefront-nextjs-shadcn/components/account/order-details.tsx +14 -12
- package/templates/storefront-nextjs-shadcn/components/account/order-history.tsx +28 -18
- package/templates/storefront-nextjs-shadcn/components/auth/account-menu.tsx +10 -8
- package/templates/storefront-nextjs-shadcn/components/auth/login-form.tsx +27 -22
- package/templates/storefront-nextjs-shadcn/components/auth/register-form.tsx +48 -43
- package/templates/storefront-nextjs-shadcn/components/blog/blog-card.tsx +1 -1
- package/templates/storefront-nextjs-shadcn/components/blog/blog-sidebar.tsx +1 -1
- package/templates/storefront-nextjs-shadcn/components/brand/brand-card.tsx +1 -1
- package/templates/storefront-nextjs-shadcn/components/cart/cart-drawer.tsx +7 -4
- package/templates/storefront-nextjs-shadcn/components/cart/cart-icon.tsx +1 -1
- package/templates/storefront-nextjs-shadcn/components/cart/cart-item.tsx +7 -5
- package/templates/storefront-nextjs-shadcn/components/cart/cart-summary.tsx +9 -7
- package/templates/storefront-nextjs-shadcn/components/cart/promo-code-input.tsx +8 -5
- package/templates/storefront-nextjs-shadcn/components/cart/shipping-estimator.tsx +18 -15
- package/templates/storefront-nextjs-shadcn/components/checkout/payment-method-card.tsx +15 -25
- package/templates/storefront-nextjs-shadcn/components/checkout/payment-step.tsx +10 -8
- package/templates/storefront-nextjs-shadcn/components/checkout/tax-breakdown.tsx +9 -6
- package/templates/storefront-nextjs-shadcn/components/commerce/currency-selector.tsx +5 -3
- package/templates/storefront-nextjs-shadcn/components/commerce/pagination.tsx +8 -5
- package/templates/storefront-nextjs-shadcn/components/commerce/product-actions.tsx +5 -3
- package/templates/storefront-nextjs-shadcn/components/commerce/search-input.tsx +8 -7
- package/templates/storefront-nextjs-shadcn/components/common/category-card.tsx +1 -1
- package/templates/storefront-nextjs-shadcn/components/common/collection-card.tsx +1 -1
- package/templates/storefront-nextjs-shadcn/components/common/social-share.tsx +9 -6
- package/templates/storefront-nextjs-shadcn/components/discount/discount-breakdown.tsx +21 -11
- package/templates/storefront-nextjs-shadcn/components/discount/discount-code-input.tsx +16 -13
- package/templates/storefront-nextjs-shadcn/components/error/error-boundary.tsx +53 -28
- package/templates/storefront-nextjs-shadcn/components/filters/dynamic-attribute-filters.tsx +7 -5
- package/templates/storefront-nextjs-shadcn/components/gift-card/gift-card-balance.tsx +19 -15
- package/templates/storefront-nextjs-shadcn/components/gift-card/gift-card-input.tsx +12 -9
- package/templates/storefront-nextjs-shadcn/components/home/category-grid.tsx +8 -5
- package/templates/storefront-nextjs-shadcn/components/home/featured-collections.tsx +1 -1
- package/templates/storefront-nextjs-shadcn/components/home/featured-products.tsx +12 -8
- package/templates/storefront-nextjs-shadcn/components/home/hero-section.tsx +13 -8
- package/templates/storefront-nextjs-shadcn/components/home/newsletter-signup.tsx +10 -8
- package/templates/storefront-nextjs-shadcn/components/layout/breadcrumbs.tsx +37 -12
- package/templates/storefront-nextjs-shadcn/components/layout/currency-selector.tsx +5 -2
- package/templates/storefront-nextjs-shadcn/components/layout/footer.tsx +24 -23
- package/templates/storefront-nextjs-shadcn/components/layout/header.tsx +20 -12
- package/templates/storefront-nextjs-shadcn/components/layout/language-switcher.tsx +54 -0
- package/templates/storefront-nextjs-shadcn/components/layout/mobile-menu.tsx +33 -30
- package/templates/storefront-nextjs-shadcn/components/layout/navigation.tsx +27 -24
- package/templates/storefront-nextjs-shadcn/components/loyalty/referral-section.tsx +23 -24
- package/templates/storefront-nextjs-shadcn/components/product/add-to-cart-button.tsx +6 -14
- package/templates/storefront-nextjs-shadcn/components/product/b2b-price-display.tsx +1 -1
- package/templates/storefront-nextjs-shadcn/components/product/filter-active-pills.tsx +4 -1
- package/templates/storefront-nextjs-shadcn/components/product/filter-mobile-sheet.tsx +7 -4
- package/templates/storefront-nextjs-shadcn/components/product/filter-price-range.tsx +5 -3
- package/templates/storefront-nextjs-shadcn/components/product/product-card.tsx +8 -6
- package/templates/storefront-nextjs-shadcn/components/product/product-filters.tsx +3 -1
- package/templates/storefront-nextjs-shadcn/components/product/product-image.tsx +3 -7
- package/templates/storefront-nextjs-shadcn/components/product/product-sort.tsx +26 -13
- package/templates/storefront-nextjs-shadcn/components/product/review-form.tsx +25 -27
- package/templates/storefront-nextjs-shadcn/components/providers/language-sync-provider.tsx +27 -0
- package/templates/storefront-nextjs-shadcn/components/providers/stores-provider.tsx +40 -7
- package/templates/storefront-nextjs-shadcn/components/returns/return-request-form.tsx +56 -70
- package/templates/storefront-nextjs-shadcn/components/search/search-bar.tsx +7 -4
- package/templates/storefront-nextjs-shadcn/components/shipping/shipping-method-selector.tsx +12 -9
- package/templates/storefront-nextjs-shadcn/components/ui/empty-state.tsx +23 -12
- package/templates/storefront-nextjs-shadcn/components/wishlist/wishlist-button.tsx +7 -4
- package/templates/storefront-nextjs-shadcn/components/wishlist/wishlist-icon.tsx +1 -1
- package/templates/storefront-nextjs-shadcn/components/wishlist/wishlist-item.tsx +2 -10
- package/templates/storefront-nextjs-shadcn/generated/graphql.ts +1159 -551
- package/templates/storefront-nextjs-shadcn/hooks/index.ts +1 -0
- package/templates/storefront-nextjs-shadcn/hooks/use-cart-actions.ts +22 -249
- package/templates/storefront-nextjs-shadcn/hooks/use-cart-di.ts +67 -0
- package/templates/storefront-nextjs-shadcn/hooks/use-cart-sync.ts +3 -3
- package/templates/storefront-nextjs-shadcn/i18n/navigation.ts +12 -0
- package/templates/storefront-nextjs-shadcn/i18n/request.ts +17 -0
- package/templates/storefront-nextjs-shadcn/i18n/routing.ts +17 -0
- package/templates/storefront-nextjs-shadcn/lib/graphql/config.ts +1 -0
- package/templates/storefront-nextjs-shadcn/lib/graphql/hooks.ts +41 -8
- package/templates/storefront-nextjs-shadcn/lib/graphql/query-keys.ts +20 -18
- package/templates/storefront-nextjs-shadcn/lib/graphql/server.ts +2 -1
- package/templates/storefront-nextjs-shadcn/messages/en.json +869 -0
- package/templates/storefront-nextjs-shadcn/messages/pl.json +869 -0
- package/templates/storefront-nextjs-shadcn/next.config.ts +6 -5
- package/templates/storefront-nextjs-shadcn/package.json +3 -2
- package/templates/storefront-nextjs-shadcn/proxy.ts +115 -46
- package/templates/storefront-nextjs-shadcn/stores/cart-store.ts +24 -58
- package/templates/storefront-nextjs-shadcn/wrangler.toml +11 -0
- /package/templates/storefront-nextjs-shadcn/app/{account → [locale]/account}/loading.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{account → [locale]/account}/orders/[id]/loading.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{blog → [locale]/blog}/[slug]/loading.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{blog → [locale]/blog}/loading.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{blog → [locale]/blog}/page.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{brands → [locale]/brands}/[slug]/page.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{brands → [locale]/brands}/page.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{cart → [locale]/cart}/loading.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{categories → [locale]/categories}/[slug]/loading.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{categories → [locale]/categories}/[slug]/page.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{checkout → [locale]/checkout}/loading.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{collections → [locale]/collections}/[handle]/loading.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{collections → [locale]/collections}/loading.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{products → [locale]/products}/[slug]/loading.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{products → [locale]/products}/loading.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{returns → [locale]/returns}/page.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{search → [locale]/search}/loading.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{search → [locale]/search}/page.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{search → [locale]/search}/search-client.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{shipping → [locale]/shipping}/page.tsx +0 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { useParams } from "next/navigation";
|
|
4
|
-
import
|
|
4
|
+
import { useTranslations } from "next-intl";
|
|
5
|
+
import { Link } from "@/i18n/navigation";
|
|
5
6
|
import { ChevronLeft } from "lucide-react";
|
|
6
7
|
import { Button } from "@/components/ui/button";
|
|
7
8
|
import { Breadcrumbs } from "@/components/layout/breadcrumbs";
|
|
@@ -19,6 +20,7 @@ import {
|
|
|
19
20
|
export default function OrderTrackingPage() {
|
|
20
21
|
const params = useParams();
|
|
21
22
|
const orderId = params.id as string;
|
|
23
|
+
const t = useTranslations("tracking");
|
|
22
24
|
|
|
23
25
|
// TODO: Fetch tracking data from backend using GraphQL
|
|
24
26
|
const trackingData = {
|
|
@@ -40,26 +42,26 @@ export default function OrderTrackingPage() {
|
|
|
40
42
|
|
|
41
43
|
const milestones = [
|
|
42
44
|
{
|
|
43
|
-
label: "
|
|
45
|
+
label: t("orderPlaced"),
|
|
44
46
|
status: "completed" as const,
|
|
45
47
|
date: "2024-01-15",
|
|
46
48
|
},
|
|
47
49
|
{
|
|
48
|
-
label: "
|
|
50
|
+
label: t("processing"),
|
|
49
51
|
status: "completed" as const,
|
|
50
52
|
date: "2024-01-16",
|
|
51
53
|
},
|
|
52
54
|
{
|
|
53
|
-
label: "
|
|
55
|
+
label: t("shipped"),
|
|
54
56
|
status: "completed" as const,
|
|
55
57
|
date: "2024-01-17",
|
|
56
58
|
},
|
|
57
59
|
{
|
|
58
|
-
label: "
|
|
60
|
+
label: t("inTransit"),
|
|
59
61
|
status: "current" as const,
|
|
60
62
|
},
|
|
61
63
|
{
|
|
62
|
-
label: "
|
|
64
|
+
label: t("delivered"),
|
|
63
65
|
status: "pending" as const,
|
|
64
66
|
},
|
|
65
67
|
];
|
|
@@ -67,40 +69,40 @@ export default function OrderTrackingPage() {
|
|
|
67
69
|
const events: TrackingEvent[] = [
|
|
68
70
|
{
|
|
69
71
|
id: "1",
|
|
70
|
-
status: "
|
|
71
|
-
description: "
|
|
72
|
+
status: t("inTransit"),
|
|
73
|
+
description: t("onTheWay"),
|
|
72
74
|
location: "Warsaw Distribution Center",
|
|
73
75
|
timestamp: "2024-01-18T14:30:00Z",
|
|
74
76
|
isCompleted: true,
|
|
75
77
|
},
|
|
76
78
|
{
|
|
77
79
|
id: "2",
|
|
78
|
-
status: "
|
|
79
|
-
description: "
|
|
80
|
+
status: t("inTransit"),
|
|
81
|
+
description: t("arrivedAtFacility"),
|
|
80
82
|
location: "Krakow Sorting Facility",
|
|
81
83
|
timestamp: "2024-01-18T08:15:00Z",
|
|
82
84
|
isCompleted: true,
|
|
83
85
|
},
|
|
84
86
|
{
|
|
85
87
|
id: "3",
|
|
86
|
-
status: "
|
|
87
|
-
description: "
|
|
88
|
+
status: t("shipped"),
|
|
89
|
+
description: t("pickedUpByCarrier"),
|
|
88
90
|
location: "Origin Facility",
|
|
89
91
|
timestamp: "2024-01-17T16:45:00Z",
|
|
90
92
|
isCompleted: true,
|
|
91
93
|
},
|
|
92
94
|
{
|
|
93
95
|
id: "4",
|
|
94
|
-
status: "
|
|
95
|
-
description: "
|
|
96
|
-
location: "
|
|
96
|
+
status: t("processing"),
|
|
97
|
+
description: t("preparingShipment"),
|
|
98
|
+
location: t("warehouse"),
|
|
97
99
|
timestamp: "2024-01-16T10:00:00Z",
|
|
98
100
|
isCompleted: true,
|
|
99
101
|
},
|
|
100
102
|
{
|
|
101
103
|
id: "5",
|
|
102
|
-
status: "
|
|
103
|
-
description: "
|
|
104
|
+
status: t("orderPlaced"),
|
|
105
|
+
description: t("orderConfirmed"),
|
|
104
106
|
timestamp: "2024-01-15T12:30:00Z",
|
|
105
107
|
isCompleted: true,
|
|
106
108
|
},
|
|
@@ -114,17 +116,17 @@ export default function OrderTrackingPage() {
|
|
|
114
116
|
<Button variant="ghost" asChild>
|
|
115
117
|
<Link href={`/account/orders/${orderId}`}>
|
|
116
118
|
<ChevronLeft className="mr-2 h-4 w-4" />
|
|
117
|
-
|
|
119
|
+
{t("backToOrderDetails")}
|
|
118
120
|
</Link>
|
|
119
121
|
</Button>
|
|
120
122
|
</div>
|
|
121
123
|
|
|
122
124
|
<div className="mb-8">
|
|
123
125
|
<h1 className="text-3xl font-bold text-foreground">
|
|
124
|
-
|
|
126
|
+
{t("trackOrder", { orderNumber: trackingData.orderNumber })}
|
|
125
127
|
</h1>
|
|
126
128
|
<p className="mt-2 text-muted-foreground">
|
|
127
|
-
|
|
129
|
+
{t("followJourney")}
|
|
128
130
|
</p>
|
|
129
131
|
</div>
|
|
130
132
|
|
|
@@ -154,7 +156,7 @@ export default function OrderTrackingPage() {
|
|
|
154
156
|
{/* Tracking Timeline */}
|
|
155
157
|
<div>
|
|
156
158
|
<h2 className="text-xl font-semibold text-foreground mb-4">
|
|
157
|
-
|
|
159
|
+
{t("trackingHistory")}
|
|
158
160
|
</h2>
|
|
159
161
|
<TrackingTimeline events={events} />
|
|
160
162
|
</div>
|
|
@@ -173,16 +175,16 @@ export default function OrderTrackingPage() {
|
|
|
173
175
|
{/* Carrier Information */}
|
|
174
176
|
<div className="rounded-lg border border-border bg-background p-6">
|
|
175
177
|
<h3 className="text-lg font-semibold text-foreground mb-4">
|
|
176
|
-
|
|
178
|
+
{t("carrierInfo")}
|
|
177
179
|
</h3>
|
|
178
180
|
<div className="space-y-3 text-sm">
|
|
179
181
|
<div>
|
|
180
|
-
<span className="font-medium text-foreground">
|
|
182
|
+
<span className="font-medium text-foreground">{t("carrier")}</span>
|
|
181
183
|
<p className="text-muted-foreground">{trackingData.carrier}</p>
|
|
182
184
|
</div>
|
|
183
185
|
<div>
|
|
184
186
|
<span className="font-medium text-foreground">
|
|
185
|
-
|
|
187
|
+
{t("trackingNumberLabel")}
|
|
186
188
|
</span>
|
|
187
189
|
<p className="font-mono text-muted-foreground">
|
|
188
190
|
{trackingData.trackingNumber}
|
|
@@ -194,7 +196,7 @@ export default function OrderTrackingPage() {
|
|
|
194
196
|
target="_blank"
|
|
195
197
|
rel="noopener noreferrer"
|
|
196
198
|
>
|
|
197
|
-
|
|
199
|
+
{t("trackOnCarrierWebsite")}
|
|
198
200
|
</a>
|
|
199
201
|
</Button>
|
|
200
202
|
</div>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import Link from "
|
|
3
|
+
import { Link } from "@/i18n/navigation";
|
|
4
|
+
import { useTranslations } from "next-intl";
|
|
4
5
|
import { useAuthStore, useAuthHydrated } from "@doswiftly/storefront-sdk/react";
|
|
5
6
|
import { useCustomer } from "@/lib/graphql/hooks";
|
|
6
7
|
import { useHydrated } from "@doswiftly/storefront-sdk/react";
|
|
@@ -9,6 +10,7 @@ import { OrderHistory } from "@/components/account/order-history";
|
|
|
9
10
|
import { Skeleton } from "@/components/ui/skeleton";
|
|
10
11
|
|
|
11
12
|
export default function OrdersPage() {
|
|
13
|
+
const t = useTranslations("account");
|
|
12
14
|
const hydrated = useHydrated();
|
|
13
15
|
const authHydrated = useAuthHydrated();
|
|
14
16
|
const accessToken = useAuthStore((s) => s.accessToken);
|
|
@@ -56,11 +58,13 @@ export default function OrdersPage() {
|
|
|
56
58
|
<div className="container mx-auto px-4 py-8">
|
|
57
59
|
<Breadcrumbs className="mb-6" />
|
|
58
60
|
<div className="rounded-lg border border-destructive bg-destructive/10 p-8 text-center text-sm text-destructive">
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
{t.rich("signInToView", {
|
|
62
|
+
link: (chunks) => (
|
|
63
|
+
<Link href="/auth/login?redirect=/account/orders" className="font-medium underline">
|
|
64
|
+
{chunks}
|
|
65
|
+
</Link>
|
|
66
|
+
),
|
|
67
|
+
})}
|
|
64
68
|
</div>
|
|
65
69
|
</div>
|
|
66
70
|
);
|
|
@@ -71,7 +75,7 @@ export default function OrdersPage() {
|
|
|
71
75
|
<div className="container mx-auto px-4 py-8">
|
|
72
76
|
<Breadcrumbs className="mb-6" />
|
|
73
77
|
<div className="rounded-lg border border-red-200 bg-red-50 p-8 text-center">
|
|
74
|
-
<p className="text-red-800">
|
|
78
|
+
<p className="text-red-800">{t("failedLoadOrders")}</p>
|
|
75
79
|
</div>
|
|
76
80
|
</div>
|
|
77
81
|
);
|
|
@@ -85,9 +89,9 @@ export default function OrdersPage() {
|
|
|
85
89
|
<Breadcrumbs className="mb-6" />
|
|
86
90
|
|
|
87
91
|
<div className="mb-8">
|
|
88
|
-
<h1 className="text-3xl font-bold text-foreground">
|
|
92
|
+
<h1 className="text-3xl font-bold text-foreground">{t("orders")}</h1>
|
|
89
93
|
<p className="mt-2 text-muted-foreground">
|
|
90
|
-
|
|
94
|
+
{t("viewTrackOrders")}
|
|
91
95
|
</p>
|
|
92
96
|
</div>
|
|
93
97
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import Link from "
|
|
4
|
-
import { useRouter } from "next/navigation";
|
|
3
|
+
import { Link, useRouter } from "@/i18n/navigation";
|
|
5
4
|
import { User, Package, MapPin, Settings } from "lucide-react";
|
|
6
5
|
import { Button } from "@/components/ui/button";
|
|
7
6
|
import { Card } from "@/components/ui/card";
|
package/templates/storefront-nextjs-shadcn/app/{account → [locale]/account}/settings/page.tsx
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { useState, useEffect } from "react";
|
|
4
|
-
import Link from "
|
|
4
|
+
import { Link } from "@/i18n/navigation";
|
|
5
5
|
import { useAuthStore, useAuthHydrated } from "@doswiftly/storefront-sdk/react";
|
|
6
6
|
import { useCustomerProfile, useCustomerUpdate } from "@/lib/graphql/hooks";
|
|
7
7
|
import { useHydrated } from "@doswiftly/storefront-sdk/react";
|
package/templates/storefront-nextjs-shadcn/app/{auth → [locale]/auth}/forgot-password/page.tsx
RENAMED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { useState } from "react";
|
|
4
|
-
import
|
|
4
|
+
import { useTranslations } from "next-intl";
|
|
5
|
+
import { Link } from "@/i18n/navigation";
|
|
5
6
|
import { useMutation } from "@tanstack/react-query";
|
|
6
7
|
import { useExecute } from "@/lib/graphql/client";
|
|
7
8
|
import {
|
|
@@ -13,6 +14,7 @@ import { Input } from "@/components/ui/input";
|
|
|
13
14
|
import { ArrowLeft } from "lucide-react";
|
|
14
15
|
|
|
15
16
|
export default function ForgotPasswordPage() {
|
|
17
|
+
const t = useTranslations("auth");
|
|
16
18
|
const execute = useExecute();
|
|
17
19
|
const [email, setEmail] = useState("");
|
|
18
20
|
const [isSubmitted, setIsSubmitted] = useState(false);
|
|
@@ -29,7 +31,7 @@ export default function ForgotPasswordPage() {
|
|
|
29
31
|
setIsSubmitted(true);
|
|
30
32
|
},
|
|
31
33
|
onError: () => {
|
|
32
|
-
setError("
|
|
34
|
+
setError(t("unexpectedError"));
|
|
33
35
|
},
|
|
34
36
|
});
|
|
35
37
|
|
|
@@ -59,25 +61,25 @@ export default function ForgotPasswordPage() {
|
|
|
59
61
|
/>
|
|
60
62
|
</svg>
|
|
61
63
|
</div>
|
|
62
|
-
<h1 className="text-3xl font-bold text-foreground">
|
|
64
|
+
<h1 className="text-3xl font-bold text-foreground">{t("checkYourEmail")}</h1>
|
|
63
65
|
<p className="mt-2 text-muted-foreground">
|
|
64
|
-
|
|
66
|
+
{t("resetEmailSent", { email })}
|
|
65
67
|
</p>
|
|
66
68
|
</div>
|
|
67
69
|
|
|
68
70
|
<div className="space-y-4">
|
|
69
71
|
<p className="text-sm text-muted-foreground">
|
|
70
|
-
|
|
72
|
+
{t("didntReceiveEmail")}
|
|
71
73
|
</p>
|
|
72
74
|
<Button variant="outline" onClick={() => setIsSubmitted(false)}>
|
|
73
|
-
|
|
75
|
+
{t("tryAnotherEmail")}
|
|
74
76
|
</Button>
|
|
75
77
|
<div>
|
|
76
78
|
<Link
|
|
77
79
|
href="/auth/login"
|
|
78
80
|
className="text-sm text-primary hover:underline"
|
|
79
81
|
>
|
|
80
|
-
|
|
82
|
+
{t("backToSignIn")}
|
|
81
83
|
</Link>
|
|
82
84
|
</div>
|
|
83
85
|
</div>
|
|
@@ -94,13 +96,13 @@ export default function ForgotPasswordPage() {
|
|
|
94
96
|
className="mb-8 inline-flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground"
|
|
95
97
|
>
|
|
96
98
|
<ArrowLeft className="h-4 w-4" />
|
|
97
|
-
|
|
99
|
+
{t("backToSignIn")}
|
|
98
100
|
</Link>
|
|
99
101
|
|
|
100
102
|
<div className="mb-8">
|
|
101
|
-
<h1 className="text-3xl font-bold text-foreground">
|
|
103
|
+
<h1 className="text-3xl font-bold text-foreground">{t("resetPasswordTitle")}</h1>
|
|
102
104
|
<p className="mt-2 text-muted-foreground">
|
|
103
|
-
|
|
105
|
+
{t("resetPasswordDescription")}
|
|
104
106
|
</p>
|
|
105
107
|
</div>
|
|
106
108
|
|
|
@@ -113,7 +115,7 @@ export default function ForgotPasswordPage() {
|
|
|
113
115
|
|
|
114
116
|
<div className="space-y-2">
|
|
115
117
|
<label htmlFor="email" className="text-sm font-medium text-foreground">
|
|
116
|
-
|
|
118
|
+
{t("email")}
|
|
117
119
|
</label>
|
|
118
120
|
<Input
|
|
119
121
|
id="email"
|
|
@@ -127,7 +129,7 @@ export default function ForgotPasswordPage() {
|
|
|
127
129
|
</div>
|
|
128
130
|
|
|
129
131
|
<Button type="submit" className="w-full" disabled={recoverMutation.isPending}>
|
|
130
|
-
{recoverMutation.isPending ? "
|
|
132
|
+
{recoverMutation.isPending ? t("sending") : t("sendResetInstructions")}
|
|
131
133
|
</Button>
|
|
132
134
|
</form>
|
|
133
135
|
</div>
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { Suspense } from "react";
|
|
4
|
+
import { useTranslations } from "next-intl";
|
|
4
5
|
import { LoginForm } from "@/components/auth/login-form";
|
|
5
6
|
import { Spinner } from "@/components/ui/spinner";
|
|
6
7
|
|
|
7
8
|
export default function LoginPage() {
|
|
9
|
+
const t = useTranslations("auth");
|
|
10
|
+
|
|
8
11
|
return (
|
|
9
12
|
<div className="container mx-auto px-4 py-16">
|
|
10
13
|
<div className="mx-auto max-w-md">
|
|
11
14
|
<div className="mb-8 text-center">
|
|
12
|
-
<h1 className="text-3xl font-bold text-foreground">
|
|
15
|
+
<h1 className="text-3xl font-bold text-foreground">{t("signInTitle")}</h1>
|
|
13
16
|
<p className="mt-2 text-muted-foreground">
|
|
14
|
-
|
|
17
|
+
{t("signInDescription")}
|
|
15
18
|
</p>
|
|
16
19
|
</div>
|
|
17
20
|
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
+
import { useTranslations } from "next-intl";
|
|
3
4
|
import { RegisterForm } from "@/components/auth/register-form";
|
|
4
5
|
|
|
5
6
|
export default function RegisterPage() {
|
|
7
|
+
const t = useTranslations("auth");
|
|
8
|
+
|
|
6
9
|
return (
|
|
7
10
|
<div className="container mx-auto px-4 py-16">
|
|
8
11
|
<div className="mx-auto max-w-md">
|
|
9
12
|
<div className="mb-8 text-center">
|
|
10
|
-
<h1 className="text-3xl font-bold text-foreground">
|
|
13
|
+
<h1 className="text-3xl font-bold text-foreground">{t("signUpTitle")}</h1>
|
|
11
14
|
<p className="mt-2 text-muted-foreground">
|
|
12
|
-
|
|
15
|
+
{t("signUpDescription")}
|
|
13
16
|
</p>
|
|
14
17
|
</div>
|
|
15
18
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import { Metadata } from 'next';
|
|
8
8
|
import Image from 'next/image';
|
|
9
|
-
import Link from '
|
|
9
|
+
import { Link } from '@/i18n/navigation';
|
|
10
10
|
import { notFound } from 'next/navigation';
|
|
11
11
|
import { Calendar, Clock, Eye, User, ChevronLeft, Share2 } from 'lucide-react';
|
|
12
12
|
import { Breadcrumbs } from '@/components/layout/breadcrumbs';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import Link from "
|
|
3
|
+
import { Link, useRouter } from "@/i18n/navigation";
|
|
4
|
+
import { useTranslations } from "next-intl";
|
|
4
5
|
import { useCartStoreApi } from "@/stores/cart-store";
|
|
5
6
|
import { useCartSync } from "@/hooks/use-cart-sync";
|
|
6
7
|
import { useCartActions } from "@/hooks/use-cart-actions";
|
|
@@ -14,6 +15,9 @@ import { Button } from "@/components/ui/button";
|
|
|
14
15
|
import { ArrowLeft, Loader2 } from "lucide-react";
|
|
15
16
|
|
|
16
17
|
export default function CartPage() {
|
|
18
|
+
const t = useTranslations("cart");
|
|
19
|
+
const router = useRouter();
|
|
20
|
+
|
|
17
21
|
// Server cart data (source of truth)
|
|
18
22
|
const {
|
|
19
23
|
items,
|
|
@@ -47,14 +51,14 @@ export default function CartPage() {
|
|
|
47
51
|
}
|
|
48
52
|
|
|
49
53
|
const handleCheckout = () => {
|
|
50
|
-
|
|
54
|
+
router.push("/checkout");
|
|
51
55
|
};
|
|
52
56
|
|
|
53
57
|
const handleApplyPromo = async (code: string) => {
|
|
54
58
|
try {
|
|
55
59
|
const cartId = cartStoreApi.getState().cartId;
|
|
56
60
|
if (!cartId) {
|
|
57
|
-
return { success: false, message: "
|
|
61
|
+
return { success: false, message: t("empty") };
|
|
58
62
|
}
|
|
59
63
|
|
|
60
64
|
const result = await discountMutation.mutateAsync({
|
|
@@ -74,15 +78,15 @@ export default function CartPage() {
|
|
|
74
78
|
if (!payload?.cart) {
|
|
75
79
|
return {
|
|
76
80
|
success: false,
|
|
77
|
-
message: "
|
|
81
|
+
message: t("promoError"),
|
|
78
82
|
};
|
|
79
83
|
}
|
|
80
84
|
|
|
81
|
-
return { success: true, message: "
|
|
85
|
+
return { success: true, message: t("promoApplied") };
|
|
82
86
|
} catch (error) {
|
|
83
87
|
return {
|
|
84
88
|
success: false,
|
|
85
|
-
message: "
|
|
89
|
+
message: t("promoError"),
|
|
86
90
|
};
|
|
87
91
|
}
|
|
88
92
|
};
|
|
@@ -104,7 +108,7 @@ export default function CartPage() {
|
|
|
104
108
|
if (items.length === 0) {
|
|
105
109
|
return (
|
|
106
110
|
<div className="container mx-auto px-4 py-16">
|
|
107
|
-
<EmptyCart onContinueShopping={() => (
|
|
111
|
+
<EmptyCart onContinueShopping={() => router.push("/products")} />
|
|
108
112
|
</div>
|
|
109
113
|
);
|
|
110
114
|
}
|
|
@@ -116,11 +120,11 @@ export default function CartPage() {
|
|
|
116
120
|
<Breadcrumbs className="mb-6" />
|
|
117
121
|
|
|
118
122
|
<div className="mb-8 flex items-center justify-between">
|
|
119
|
-
<h1 className="text-3xl font-bold text-foreground">
|
|
123
|
+
<h1 className="text-3xl font-bold text-foreground">{t("title")}</h1>
|
|
120
124
|
<Button variant="ghost" asChild>
|
|
121
125
|
<Link href="/products">
|
|
122
126
|
<ArrowLeft className="mr-2 h-4 w-4" />
|
|
123
|
-
|
|
127
|
+
{t("continueShopping")}
|
|
124
128
|
</Link>
|
|
125
129
|
</Button>
|
|
126
130
|
</div>
|
|
@@ -144,7 +148,7 @@ export default function CartPage() {
|
|
|
144
148
|
{/* Summary */}
|
|
145
149
|
<div className="lg:col-span-1">
|
|
146
150
|
<div className="sticky top-4 space-y-4 rounded-lg border border-border bg-muted/50 p-6">
|
|
147
|
-
<h2 className="text-lg font-semibold text-foreground">
|
|
151
|
+
<h2 className="text-lg font-semibold text-foreground">{t("yourOrder")}</h2>
|
|
148
152
|
|
|
149
153
|
<PromoCodeInput
|
|
150
154
|
onApply={handleApplyPromo}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
+
import { useTranslations } from "next-intl";
|
|
3
4
|
import { ProductGrid } from "@/components/product/product-grid";
|
|
4
5
|
import { Skeleton } from "@/components/ui/skeleton";
|
|
5
6
|
import { useProducts } from "@/lib/graphql/hooks";
|
|
@@ -17,6 +18,7 @@ interface CategoryProductsClientProps {
|
|
|
17
18
|
export function CategoryProductsClient({
|
|
18
19
|
categoryId,
|
|
19
20
|
}: CategoryProductsClientProps) {
|
|
21
|
+
const t = useTranslations("product");
|
|
20
22
|
const { data, isLoading, error } = useProducts({
|
|
21
23
|
first: 20,
|
|
22
24
|
filters: { categoryId },
|
|
@@ -38,7 +40,7 @@ export function CategoryProductsClient({
|
|
|
38
40
|
return (
|
|
39
41
|
<div className="rounded-lg border border-border bg-muted/50 p-12 text-center">
|
|
40
42
|
<p className="text-muted-foreground">
|
|
41
|
-
|
|
43
|
+
{t("failedLoadProducts")}
|
|
42
44
|
</p>
|
|
43
45
|
</div>
|
|
44
46
|
);
|
|
@@ -50,7 +52,7 @@ export function CategoryProductsClient({
|
|
|
50
52
|
columns={4}
|
|
51
53
|
priorityCount={8}
|
|
52
54
|
showBadges
|
|
53
|
-
emptyMessage="
|
|
55
|
+
emptyMessage={t("noProductsInCategory")}
|
|
54
56
|
/>
|
|
55
57
|
);
|
|
56
58
|
}
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
import { Metadata } from "next";
|
|
2
|
-
import
|
|
2
|
+
import { getTranslations } from "next-intl/server";
|
|
3
|
+
import { Link } from "@/i18n/navigation";
|
|
3
4
|
import { Card } from "@/components/ui/card";
|
|
4
5
|
import { fetchCategories } from "@/lib/graphql/server";
|
|
5
6
|
import type { CategoryNodeFields } from "@/lib/graphql/fragments";
|
|
6
7
|
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
export async function generateMetadata(): Promise<Metadata> {
|
|
9
|
+
const t = await getTranslations("categories");
|
|
10
|
+
return {
|
|
11
|
+
title: t("title"),
|
|
12
|
+
description: t("description"),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
11
15
|
|
|
12
16
|
// Enable ISR with 60 second revalidation
|
|
13
17
|
export const revalidate = 60;
|
|
14
18
|
|
|
15
19
|
export default async function CategoriesPage() {
|
|
20
|
+
const t = await getTranslations("categories");
|
|
16
21
|
let categoryList: CategoryNodeFields[] = [];
|
|
17
22
|
|
|
18
23
|
try {
|
|
@@ -25,15 +30,15 @@ export default async function CategoriesPage() {
|
|
|
25
30
|
return (
|
|
26
31
|
<div className="container mx-auto px-4 py-8">
|
|
27
32
|
<div className="mb-8">
|
|
28
|
-
<h1 className="text-3xl font-bold text-foreground">
|
|
33
|
+
<h1 className="text-3xl font-bold text-foreground">{t("title")}</h1>
|
|
29
34
|
<p className="mt-2 text-muted-foreground">
|
|
30
|
-
|
|
35
|
+
{t("description")}
|
|
31
36
|
</p>
|
|
32
37
|
</div>
|
|
33
38
|
|
|
34
39
|
{categoryList.length === 0 ? (
|
|
35
40
|
<div className="rounded-lg border border-border bg-muted/50 p-12 text-center">
|
|
36
|
-
<p className="text-muted-foreground">
|
|
41
|
+
<p className="text-muted-foreground">{t("noCategories")}</p>
|
|
37
42
|
</div>
|
|
38
43
|
) : (
|
|
39
44
|
<div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { useEffect } from "react";
|
|
4
|
-
import Link from "
|
|
4
|
+
import { Link } from "@/i18n/navigation";
|
|
5
5
|
import { AlertCircle } from "lucide-react";
|
|
6
6
|
import { Button } from "@/components/ui/button";
|
|
7
7
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|