@akinon/projectzero 2.0.0-beta.0 → 2.0.0-beta.10
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/CHANGELOG.md +41 -0
- package/app-template/.env.example +5 -0
- package/app-template/.gitignore +2 -0
- package/app-template/CHANGELOG.md +250 -0
- package/app-template/README.md +6 -0
- package/app-template/config/prebuild-tests.json +5 -0
- package/app-template/next-env.d.ts +1 -1
- package/app-template/{next.config.mjs → next.config.ts} +6 -3
- package/app-template/package.json +43 -40
- package/app-template/postcss.config.mjs +8 -0
- package/app-template/public/locales/en/account.json +4 -0
- package/app-template/public/locales/en/common.json +10 -0
- package/app-template/public/locales/tr/account.json +4 -0
- package/app-template/public/locales/tr/common.json +10 -0
- package/app-template/src/__tests__/middleware-matcher.test.ts +135 -0
- package/app-template/src/app/[commerce]/[locale]/[currency]/[...prettyurl]/page.tsx +6 -4
- package/app-template/src/app/[commerce]/[locale]/[currency]/account/orders/[id]/cancellation/page.tsx +98 -7
- package/app-template/src/app/[commerce]/[locale]/[currency]/account/orders/[id]/page.tsx +71 -7
- package/app-template/src/app/[commerce]/[locale]/[currency]/account/page.tsx +1 -1
- package/app-template/src/app/[commerce]/[locale]/[currency]/account/profile/page.tsx +1 -1
- package/app-template/src/app/[commerce]/[locale]/[currency]/address/stores/page.tsx +2 -2
- package/app-template/src/app/[commerce]/[locale]/[currency]/auth/page.tsx +1 -1
- package/app-template/src/app/[commerce]/[locale]/[currency]/basket/page.tsx +2 -2
- package/app-template/src/app/[commerce]/[locale]/[currency]/category/[pk]/page.tsx +4 -1
- package/app-template/src/app/[commerce]/[locale]/[currency]/error.tsx +12 -15
- package/app-template/src/app/[commerce]/[locale]/[currency]/flat-page/[pk]/page.tsx +3 -1
- package/app-template/src/app/[commerce]/[locale]/[currency]/forms/[pk]/generate/page.tsx +5 -3
- package/app-template/src/app/[commerce]/[locale]/[currency]/group-product/[pk]/page.tsx +7 -5
- package/app-template/src/app/[commerce]/[locale]/[currency]/landing-page/[pk]/page.tsx +3 -1
- package/app-template/src/app/[commerce]/[locale]/[currency]/layout.tsx +3 -1
- package/app-template/src/app/[commerce]/[locale]/[currency]/list/page.tsx +3 -1
- package/app-template/src/app/[commerce]/[locale]/[currency]/{pz-not-found/page.tsx → not-found.tsx} +2 -2
- package/app-template/src/app/[commerce]/[locale]/[currency]/orders/checkout/page.tsx +7 -4
- package/app-template/src/app/[commerce]/[locale]/[currency]/orders/completed/[token]/page.tsx +3 -7
- package/app-template/src/app/[commerce]/[locale]/[currency]/product/[pk]/page.tsx +8 -5
- package/app-template/src/app/[commerce]/[locale]/[currency]/special-page/[pk]/page.tsx +3 -1
- package/app-template/src/app/[commerce]/[locale]/[currency]/users/email-set-primary/[[...id]]/page.tsx +4 -1
- package/app-template/src/app/[commerce]/[locale]/[currency]/users/registration/account-confirm-email/[[...id]]/page.tsx +3 -1
- package/app-template/src/app/[commerce]/[locale]/[currency]/users/reset/[[...id]]/page.tsx +11 -3
- package/app-template/src/app/[commerce]/[locale]/[currency]/xml-sitemap/[node]/route.ts +48 -2
- package/app-template/src/assets/globals.scss +162 -34
- package/app-template/src/components/__tests__/badge.test.tsx +2 -2
- package/app-template/src/components/accordion.tsx +1 -1
- package/app-template/src/components/button.tsx +50 -35
- package/app-template/src/components/file-input.tsx +44 -2
- package/app-template/src/components/input.tsx +3 -3
- package/app-template/src/components/modal.tsx +1 -1
- package/app-template/src/components/pwa-tags.tsx +0 -1
- package/app-template/src/components/select.tsx +2 -2
- package/app-template/src/components/shimmer.tsx +1 -1
- package/app-template/src/components/tabs.tsx +2 -2
- package/app-template/src/components/types/index.ts +4 -1
- package/app-template/src/middleware.ts +1 -0
- package/app-template/src/plugins.js +2 -1
- package/app-template/src/redux/middlewares/category.ts +1 -1
- package/app-template/src/redux/reducers/category.ts +1 -1
- package/app-template/src/redux/store.ts +4 -3
- package/app-template/src/settings.js +1 -2
- package/app-template/src/utils/convert-facet-search-params.ts +1 -1
- package/app-template/src/views/account/address-form.tsx +2 -2
- package/app-template/src/views/account/contact-form.tsx +4 -9
- package/app-template/src/views/account/content-header.tsx +2 -3
- package/app-template/src/views/account/order.tsx +1 -1
- package/app-template/src/views/account/orders/order-cancellation-item.tsx +5 -4
- package/app-template/src/views/anonymous-tracking/order-detail/index.tsx +1 -1
- package/app-template/src/views/basket/basket-item.tsx +1 -0
- package/app-template/src/views/category/category-active-filters.tsx +1 -1
- package/app-template/src/views/category/category-header.tsx +12 -6
- package/app-template/src/views/category/category-info.tsx +4 -4
- package/app-template/src/views/category/filters/index.tsx +2 -2
- package/app-template/src/views/checkout/auth.tsx +1 -1
- package/app-template/src/views/checkout/layout/header.tsx +1 -1
- package/app-template/src/views/checkout/steps/payment/index.tsx +1 -1
- package/app-template/src/views/checkout/steps/payment/options/credit-card/index.tsx +1 -1
- package/app-template/src/views/checkout/steps/payment/payment-option-buttons.tsx +4 -4
- package/app-template/src/views/checkout/steps/shipping/address-box.tsx +3 -3
- package/app-template/src/views/checkout/steps/shipping/addresses.tsx +1 -1
- package/app-template/src/views/checkout/summary.tsx +2 -2
- package/app-template/src/views/guest-login/index.tsx +1 -1
- package/app-template/src/views/header/action-menu.tsx +6 -3
- package/app-template/src/views/header/band.tsx +2 -2
- package/app-template/src/views/header/mini-basket.tsx +16 -5
- package/app-template/src/views/header/mobile-menu.tsx +6 -6
- package/app-template/src/views/header/navbar.tsx +1 -1
- package/app-template/src/views/header/pwa-back-button.tsx +1 -1
- package/app-template/src/views/header/search/index.tsx +16 -4
- package/app-template/src/views/header/search/results.tsx +1 -1
- package/app-template/src/views/header/user-menu.tsx +3 -1
- package/app-template/src/views/installment-options/index.tsx +1 -1
- package/app-template/src/views/login/index.tsx +30 -6
- package/app-template/src/views/otp-login/index.tsx +13 -15
- package/app-template/src/views/product/product-info.tsx +2 -2
- package/app-template/src/views/product/slider.tsx +1 -1
- package/app-template/src/views/product-pointer-banner-item.tsx +1 -1
- package/app-template/src/views/register/index.tsx +30 -5
- package/app-template/src/views/sales-contract-modal/index.tsx +17 -17
- package/app-template/src/widgets/footer-info.tsx +1 -1
- package/app-template/src/widgets/footer-menu.tsx +1 -1
- package/app-template/src/widgets/footer-subscription/index.tsx +1 -1
- package/app-template/src/widgets/home-stories-eng.tsx +1 -1
- package/app-template/tailwind.config.js +1 -137
- package/codemods/sentry-9/index.js +30 -0
- package/codemods/sentry-9/remove-sentry-configs.js +14 -0
- package/codemods/sentry-9/remove-sentry-dependency.js +25 -0
- package/codemods/sentry-9/replace-error-page.js +32 -0
- package/commands/codemod.ts +18 -0
- package/commands/index.ts +3 -1
- package/commands/plugins.ts +4 -0
- package/dist/codemods/sentry-9/templates/error.js +14 -0
- package/dist/commands/codemod.js +16 -0
- package/dist/commands/commerce-url.js +17 -7
- package/dist/commands/create.js +17 -7
- package/dist/commands/index.js +3 -1
- package/dist/commands/plugins.js +21 -7
- package/package.json +1 -1
- package/app-template/postcss.config.js +0 -6
- package/app-template/sentry.client.config.ts +0 -16
- package/app-template/sentry.edge.config.ts +0 -3
- package/app-template/sentry.properties +0 -4
- package/app-template/sentry.server.config.ts +0 -3
- package/app-template/src/app/[commerce]/[locale]/[currency]/product/[pk]/loading.tsx +0 -67
|
@@ -39,8 +39,8 @@ export const Input = forwardRef<
|
|
|
39
39
|
const hasFloatingLabel = label && labelStyle === 'floating';
|
|
40
40
|
const inputClass = twMerge(
|
|
41
41
|
clsx(
|
|
42
|
-
'text-xs border px-2.5 h-10 placeholder:text-gray-600 peer',
|
|
43
|
-
'focus-visible:outline-
|
|
42
|
+
'text-xs border px-2.5 h-10 placeholder:text-gray-600 peer disabled:bg-gray-50',
|
|
43
|
+
'focus-visible:outline-hidden', // disable outline on focus
|
|
44
44
|
error
|
|
45
45
|
? 'border-error focus:border-error'
|
|
46
46
|
: 'border-gray-500 hover:border-black focus:border-black'
|
|
@@ -68,7 +68,7 @@ export const Input = forwardRef<
|
|
|
68
68
|
className={twMerge(
|
|
69
69
|
'text-xs text-gray-800 transition-all',
|
|
70
70
|
clsx({
|
|
71
|
-
'absolute left-2.5 pointer-events-none transform flex items-center h-full
|
|
71
|
+
'absolute left-2.5 pointer-events-none transform flex items-center h-full top-0! peer-placeholder-shown:-translate-y-2 peer-placeholder-shown:bg-white peer-placeholder-shown:inline-flex peer-placeholder-shown:h-auto':
|
|
72
72
|
hasFloatingLabel,
|
|
73
73
|
'mb-2': !hasFloatingLabel,
|
|
74
74
|
'-translate-y-2 bg-white inline-flex h-auto':
|
|
@@ -38,7 +38,7 @@ export const Modal = (props: ModalProps) => {
|
|
|
38
38
|
|
|
39
39
|
return (
|
|
40
40
|
<ReactPortal wrapperId={portalId}>
|
|
41
|
-
<div className="fixed top-0 left-0 w-screen h-screen bg-primary
|
|
41
|
+
<div className="fixed top-0 left-0 w-screen h-screen bg-primary/60 z-50" />
|
|
42
42
|
<section
|
|
43
43
|
className={twMerge(
|
|
44
44
|
'fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-50 bg-white',
|
|
@@ -41,14 +41,14 @@ const Select = forwardRef<HTMLSelectElement, SelectProps>((props, ref) => {
|
|
|
41
41
|
ref={ref}
|
|
42
42
|
className={twMerge(
|
|
43
43
|
clsx(
|
|
44
|
-
'cursor-pointer truncate h-10 w-40 px-2.5 shrink-0 outline-
|
|
44
|
+
'cursor-pointer truncate h-10 w-40 px-2.5 shrink-0 outline-hidden',
|
|
45
45
|
!borderless &&
|
|
46
46
|
'border border-gray-200 transition-all duration-150 hover:border-primary'
|
|
47
47
|
),
|
|
48
48
|
className
|
|
49
49
|
)}
|
|
50
50
|
>
|
|
51
|
-
{options
|
|
51
|
+
{options?.map((option) => (
|
|
52
52
|
<option
|
|
53
53
|
key={option.value}
|
|
54
54
|
value={option.value}
|
|
@@ -12,7 +12,7 @@ export const Shimmer: React.FC<ShimmerProps> = ({ className }) => {
|
|
|
12
12
|
>
|
|
13
13
|
<div
|
|
14
14
|
className={twMerge(
|
|
15
|
-
'w-full h-full bg-black
|
|
15
|
+
'w-full h-full bg-black/20 shadow-[0 0 30px 30px rgba(255,255,255,0.2)]',
|
|
16
16
|
className
|
|
17
17
|
)}
|
|
18
18
|
></div>
|
|
@@ -39,7 +39,7 @@ export const Tabs = (props: Props) => {
|
|
|
39
39
|
tabBarPosition === 'left' || tabBarPosition === 'right'
|
|
40
40
|
})}
|
|
41
41
|
>
|
|
42
|
-
{children
|
|
42
|
+
{children?.map((item, index) => (
|
|
43
43
|
<Tab
|
|
44
44
|
key={item.props.title}
|
|
45
45
|
title={item.props.title}
|
|
@@ -52,7 +52,7 @@ export const Tabs = (props: Props) => {
|
|
|
52
52
|
))}
|
|
53
53
|
</ul>
|
|
54
54
|
|
|
55
|
-
<div className="w-full">{children[selectedTabIndex]}</div>
|
|
55
|
+
<div className="w-full">{children?.[selectedTabIndex]}</div>
|
|
56
56
|
</div>
|
|
57
57
|
);
|
|
58
58
|
};
|
|
@@ -4,7 +4,10 @@ import { UsePaginationType } from '@akinon/next/hooks/use-pagination';
|
|
|
4
4
|
|
|
5
5
|
export interface ButtonProps
|
|
6
6
|
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
7
|
-
appearance?: 'filled' | 'outlined' | 'ghost';
|
|
7
|
+
appearance?: 'filled' | 'outlined' | 'ghost' | 'link' | string;
|
|
8
|
+
size?: 'sm' | 'md' | 'lg' | 'xl';
|
|
9
|
+
href?: string;
|
|
10
|
+
target?: '_blank' | '_self' | '_parent' | '_top';
|
|
8
11
|
}
|
|
9
12
|
|
|
10
13
|
export interface PaginationProps {
|
|
@@ -9,6 +9,7 @@ import { NextMiddleware, NextResponse } from 'next/server';
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
export const config = {
|
|
12
|
+
// For .xml.gz type sitemap urls, update '/(.*sitemap\\.xml)' with this regex '/(.*sitemap\\.xml|sitemap/.*.xml(?:.gz)?)/',
|
|
12
13
|
matcher: [
|
|
13
14
|
'/((?!api|_next|[\\w-\\/*]+\\.\\w+).*)',
|
|
14
15
|
'/(.*sitemap\\.xml)',
|
|
@@ -32,7 +32,7 @@ const categorySlice = createSlice({
|
|
|
32
32
|
toggleFacet(state, action) {
|
|
33
33
|
const facets = JSON.parse(JSON.stringify(state.facets));
|
|
34
34
|
|
|
35
|
-
state.selectedFacets = facets
|
|
35
|
+
state.selectedFacets = facets?.map((facet) => {
|
|
36
36
|
if (facet.key === action.payload.facet.key) {
|
|
37
37
|
facet.data.choices = facet.data.choices
|
|
38
38
|
.map((choice) => {
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
Action,
|
|
7
7
|
AnyAction,
|
|
8
8
|
configureStore,
|
|
9
|
+
Middleware,
|
|
9
10
|
Store,
|
|
10
11
|
ThunkAction,
|
|
11
12
|
ThunkDispatch
|
|
@@ -13,20 +14,20 @@ import {
|
|
|
13
14
|
import categoryReducer from '@theme/redux/reducers/category';
|
|
14
15
|
import categoryMiddleware from '@theme/redux/middlewares/category';
|
|
15
16
|
|
|
17
|
+
const _middlewares: Middleware[] = [...middlewares, categoryMiddleware];
|
|
18
|
+
|
|
16
19
|
const _reducers = {
|
|
17
20
|
...reducers,
|
|
18
21
|
category: categoryReducer
|
|
19
22
|
};
|
|
20
23
|
|
|
21
|
-
const _middlewares = [...middlewares, categoryMiddleware];
|
|
22
|
-
|
|
23
24
|
export const makeStore = (): Store<{
|
|
24
25
|
[key in keyof typeof _reducers]: ReturnType<typeof _reducers[key]>;
|
|
25
26
|
}> =>
|
|
26
27
|
configureStore({
|
|
27
28
|
reducer: _reducers,
|
|
28
29
|
middleware: (getDefaultMiddleware) =>
|
|
29
|
-
getDefaultMiddleware().concat(
|
|
30
|
+
getDefaultMiddleware().concat(_middlewares)
|
|
30
31
|
});
|
|
31
32
|
|
|
32
33
|
export type AppStore = ReturnType<typeof makeStore>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Facet } from '@akinon/next/types';
|
|
2
2
|
|
|
3
3
|
const convertFacetSearchParams = (facets: Facet[]) => {
|
|
4
|
-
const _facets: string[][] = facets
|
|
4
|
+
const _facets: string[][] = facets?.flatMap((facet) => {
|
|
5
5
|
return [
|
|
6
6
|
...facet.data.choices.map((choice) => {
|
|
7
7
|
return [facet.search_key, choice.value as string];
|
|
@@ -247,7 +247,7 @@ export const AddressForm = (props: Props) => {
|
|
|
247
247
|
/>
|
|
248
248
|
<Input
|
|
249
249
|
label={t('account.address_book.form.phone.placeholder')}
|
|
250
|
-
format={config.user_phone_format.replaceAll(
|
|
250
|
+
format={config.user_phone_format.replaceAll(/9/g, '#')}
|
|
251
251
|
mask="_"
|
|
252
252
|
allowEmptyFormatting={true}
|
|
253
253
|
control={control}
|
|
@@ -339,7 +339,7 @@ export const AddressForm = (props: Props) => {
|
|
|
339
339
|
error={errors.postcode}
|
|
340
340
|
data-testid="address-form-post-code"
|
|
341
341
|
required
|
|
342
|
-
format={config.user_post_code_format.replaceAll(
|
|
342
|
+
format={config.user_post_code_format.replaceAll(/9/g, '#')}
|
|
343
343
|
control={control}
|
|
344
344
|
mask="_"
|
|
345
345
|
allowEmptyFormatting
|
|
@@ -192,7 +192,7 @@ const ContactForm = () => {
|
|
|
192
192
|
label={t('account.contact.form.phone.placeholder')}
|
|
193
193
|
type="tel"
|
|
194
194
|
className="mb-1"
|
|
195
|
-
format={user_phone_format.replace(
|
|
195
|
+
format={user_phone_format.replace(/9/g, '#')}
|
|
196
196
|
mask="_"
|
|
197
197
|
allowEmptyFormatting={true}
|
|
198
198
|
control={control}
|
|
@@ -242,7 +242,7 @@ const ContactForm = () => {
|
|
|
242
242
|
<span className="text-secondary">*</span>
|
|
243
243
|
</label>
|
|
244
244
|
<textarea
|
|
245
|
-
className="border-gray-500 border w-full text-xs p-2.5 focus-visible:outline-
|
|
245
|
+
className="border-gray-500 border w-full text-xs p-2.5 focus-visible:outline-hidden focus:border-black hover:border-black"
|
|
246
246
|
rows={7}
|
|
247
247
|
name="message"
|
|
248
248
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
@@ -255,13 +255,8 @@ const ContactForm = () => {
|
|
|
255
255
|
<label className="text-xs text-gray-800 mb-2 block">
|
|
256
256
|
{t('account.contact.form.file.title')}
|
|
257
257
|
</label>
|
|
258
|
-
<FileInput
|
|
259
|
-
|
|
260
|
-
title="file"
|
|
261
|
-
className="w-full mb-5"
|
|
262
|
-
{...register('file')}
|
|
263
|
-
/>
|
|
264
|
-
<Button type="submit" className="w-full font-medium">
|
|
258
|
+
<FileInput name="file" title="file" {...register('file')} />
|
|
259
|
+
<Button type="submit" className="w-full font-medium mt-4">
|
|
265
260
|
{t('account.contact.form.submit_button')}
|
|
266
261
|
</Button>
|
|
267
262
|
</form>
|
|
@@ -31,15 +31,14 @@ export const ContentHeader = (props: Props) => {
|
|
|
31
31
|
</h3>
|
|
32
32
|
<Select
|
|
33
33
|
onChange={handleChange}
|
|
34
|
-
className="w-full mb-4 md:mb-0 md:w-56 md:mr-4 text-xs"
|
|
34
|
+
className="w-full mb-4 bg-white md:mb-0 md:w-56 md:mr-4 text-xs"
|
|
35
35
|
options={orders}
|
|
36
36
|
data-testid="account-orders-header-select"
|
|
37
37
|
></Select>
|
|
38
38
|
<Button
|
|
39
39
|
className={clsx(
|
|
40
40
|
'w-full md:w-56',
|
|
41
|
-
isButtonDisabled &&
|
|
42
|
-
'hover:bg-black hover:text-white disabled:opacity-75'
|
|
41
|
+
isButtonDisabled && 'hover:bg-black/75 hover:text-white'
|
|
43
42
|
)}
|
|
44
43
|
onClick={handleClick}
|
|
45
44
|
data-testid="account-orders-header-button"
|
|
@@ -60,7 +60,7 @@ export const Order = (props) => {
|
|
|
60
60
|
<ul className="flex flex-wrap gap-3.5 mb-6 items-center md:mb-0">
|
|
61
61
|
{props.orderitem_set.slice(0, 3).map((item, index) => (
|
|
62
62
|
// TODO: Static image will change (TR)
|
|
63
|
-
<li className="
|
|
63
|
+
<li className="shrink-0" key={index}>
|
|
64
64
|
<Image
|
|
65
65
|
src={item.product.image ? item.product.image : '/noimage.jpg'}
|
|
66
66
|
alt={item.product.name}
|
|
@@ -8,7 +8,8 @@ export const OrderCancellationItem = ({
|
|
|
8
8
|
item,
|
|
9
9
|
value,
|
|
10
10
|
onChange,
|
|
11
|
-
selectOption
|
|
11
|
+
selectOption,
|
|
12
|
+
fileInput
|
|
12
13
|
}) => {
|
|
13
14
|
const { t } = useLocalization();
|
|
14
15
|
const checkboxStatus =
|
|
@@ -38,14 +39,13 @@ export const OrderCancellationItem = ({
|
|
|
38
39
|
<div className="flex flex-wrap justify-between border-gray border-b mb-4 pb-3">
|
|
39
40
|
<div className="flex gap-3 mb-5 lg:mb-0">
|
|
40
41
|
{checkboxStatus && (
|
|
41
|
-
// TODO: Static image will change (TR)
|
|
42
42
|
<Checkbox
|
|
43
43
|
className="m-auto"
|
|
44
44
|
data-testid="account-orders-return-checkbox"
|
|
45
45
|
onClick={handleClick}
|
|
46
46
|
/>
|
|
47
47
|
)}
|
|
48
|
-
<div className="
|
|
48
|
+
<div className="shrink-0">
|
|
49
49
|
<Link href={item.product.absolute_url}>
|
|
50
50
|
<Image
|
|
51
51
|
src={item.product.image ? item.product.image : '/noimage.jpg'}
|
|
@@ -80,7 +80,7 @@ export const OrderCancellationItem = ({
|
|
|
80
80
|
</div>
|
|
81
81
|
</div>
|
|
82
82
|
</div>
|
|
83
|
-
<div className="flex flex-wrap justify-between w-full items-start lg:items-center lg:w-
|
|
83
|
+
<div className="flex flex-wrap justify-between w-full items-start lg:items-center lg:w-80 gap-4">
|
|
84
84
|
<div className="w-full flex flex-col lg:items-center lg:flex-row">
|
|
85
85
|
{item.active_cancellation_request?.easy_return?.code && (
|
|
86
86
|
<div className="flex items-center">
|
|
@@ -93,6 +93,7 @@ export const OrderCancellationItem = ({
|
|
|
93
93
|
|
|
94
94
|
{selectOption}
|
|
95
95
|
</div>
|
|
96
|
+
<div>{fileInput}</div>
|
|
96
97
|
</div>
|
|
97
98
|
</div>
|
|
98
99
|
);
|
|
@@ -135,7 +135,7 @@ export const AnonymousTrackingOrderDetail = ({ order }) => {
|
|
|
135
135
|
key={index}
|
|
136
136
|
>
|
|
137
137
|
<div className="flex gap-3 mb-5 lg:mb-0">
|
|
138
|
-
<div className="
|
|
138
|
+
<div className="shrink-0">
|
|
139
139
|
<Link
|
|
140
140
|
className="block"
|
|
141
141
|
href={item.product.absolute_url}
|
|
@@ -87,6 +87,7 @@ export const BasketItem = (props: Props) => {
|
|
|
87
87
|
<li
|
|
88
88
|
key={basketItem.id}
|
|
89
89
|
className="flex border-b border-gray-200 py-3 relative"
|
|
90
|
+
data-testid="basket-item"
|
|
90
91
|
>
|
|
91
92
|
<div className="w-20 lg:w-[105px] mr-4 shrink-0">
|
|
92
93
|
<Link href={basketItem.product.absolute_url} passHref>
|
|
@@ -69,7 +69,7 @@ const CategoryActiveFilters = () => {
|
|
|
69
69
|
|
|
70
70
|
return (
|
|
71
71
|
<div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-2 mb-4">
|
|
72
|
-
{facets
|
|
72
|
+
{facets?.map((facet) =>
|
|
73
73
|
facet?.data?.choices
|
|
74
74
|
?.filter((choice) => choice.is_selected)
|
|
75
75
|
?.map(
|
|
@@ -91,12 +91,18 @@ export const CategoryHeader = (props: Props) => {
|
|
|
91
91
|
value: String(value)
|
|
92
92
|
});
|
|
93
93
|
}}
|
|
94
|
-
className=
|
|
95
|
-
'cursor-pointer',
|
|
96
|
-
Number(layoutSize) === value ? 'fill-black' : 'fill-gray-500'
|
|
97
|
-
)}
|
|
94
|
+
className="cursor-pointer"
|
|
98
95
|
>
|
|
99
|
-
<Icon
|
|
96
|
+
<Icon
|
|
97
|
+
key={value}
|
|
98
|
+
name={icon}
|
|
99
|
+
size={16}
|
|
100
|
+
className={
|
|
101
|
+
Number(layoutSize) === value
|
|
102
|
+
? 'text-black'
|
|
103
|
+
: 'text-gray-500'
|
|
104
|
+
}
|
|
105
|
+
/>
|
|
100
106
|
</a>
|
|
101
107
|
))}
|
|
102
108
|
</div>
|
|
@@ -115,7 +121,7 @@ export const CategoryHeader = (props: Props) => {
|
|
|
115
121
|
</Button>
|
|
116
122
|
<Select
|
|
117
123
|
options={sortOptions}
|
|
118
|
-
value={sortOptions
|
|
124
|
+
value={sortOptions?.find(({ is_selected }) => is_selected)?.value}
|
|
119
125
|
data-testid="list-sorter"
|
|
120
126
|
onChange={(e) => {
|
|
121
127
|
handleSelectFilter({
|
|
@@ -79,7 +79,7 @@ export default function ListPage(props: ListPageProps) {
|
|
|
79
79
|
className={clsx(
|
|
80
80
|
'transition-opacity duration-300 ease-linear lg:hidden',
|
|
81
81
|
isMenuOpen
|
|
82
|
-
? 'fixed bg-black
|
|
82
|
+
? 'fixed bg-black/60 inset-0 z-10 opacity-100'
|
|
83
83
|
: 'opacity-0'
|
|
84
84
|
)}
|
|
85
85
|
></div>
|
|
@@ -102,7 +102,7 @@ export default function ListPage(props: ListPageProps) {
|
|
|
102
102
|
</div>
|
|
103
103
|
)}
|
|
104
104
|
|
|
105
|
-
{data.products
|
|
105
|
+
{data.products?.length === 0 && page > 1 && <LoaderSpinner />}
|
|
106
106
|
|
|
107
107
|
<div
|
|
108
108
|
className={clsx('grid gap-x-4 gap-y-12 grid-cols-2', {
|
|
@@ -111,7 +111,7 @@ export default function ListPage(props: ListPageProps) {
|
|
|
111
111
|
'lg:grid-cols-3': layoutSize === 3
|
|
112
112
|
})}
|
|
113
113
|
>
|
|
114
|
-
{data
|
|
114
|
+
{data?.products?.map((product, index) => (
|
|
115
115
|
<ProductItem
|
|
116
116
|
key={product.pk}
|
|
117
117
|
product={product}
|
|
@@ -121,7 +121,7 @@ export default function ListPage(props: ListPageProps) {
|
|
|
121
121
|
/>
|
|
122
122
|
))}
|
|
123
123
|
</div>
|
|
124
|
-
{data
|
|
124
|
+
{data?.products?.length > 0 && (
|
|
125
125
|
<Pagination
|
|
126
126
|
total={data.pagination.total_count}
|
|
127
127
|
limit={data.pagination.page_size}
|
|
@@ -23,7 +23,7 @@ export const Filters = (props: Props) => {
|
|
|
23
23
|
const [isPending, startTransition] = useTransition();
|
|
24
24
|
|
|
25
25
|
const haveFilter = useMemo(() => {
|
|
26
|
-
return facets
|
|
26
|
+
return facets?.some((facet) =>
|
|
27
27
|
facet?.data?.choices?.some((choice) => choice.is_selected)
|
|
28
28
|
);
|
|
29
29
|
}, [facets]);
|
|
@@ -50,7 +50,7 @@ export const Filters = (props: Props) => {
|
|
|
50
50
|
<span>{t('category.filters.ready_to_wear')}</span>
|
|
51
51
|
</div>
|
|
52
52
|
|
|
53
|
-
{facets
|
|
53
|
+
{facets?.map((facet) => {
|
|
54
54
|
return (
|
|
55
55
|
<FilterItem
|
|
56
56
|
key={facet.key}
|
|
@@ -24,7 +24,7 @@ const CheckoutAuth = () => {
|
|
|
24
24
|
|
|
25
25
|
return (
|
|
26
26
|
<div className="flex flex-col w-full my-5 lg:flex-row">
|
|
27
|
-
<div className="flex-1
|
|
27
|
+
<div className="flex-1 shrink-0">
|
|
28
28
|
<Login />
|
|
29
29
|
<div className="text-center text-sm text-gray-600 uppercase mt-5">
|
|
30
30
|
<span>
|
|
@@ -6,7 +6,7 @@ import { Image } from '@akinon/next/components/image';
|
|
|
6
6
|
|
|
7
7
|
const CheckoutHeader = () => {
|
|
8
8
|
return (
|
|
9
|
-
<div className="relative border-b border-gray-100 shadow">
|
|
9
|
+
<div className="relative border-b border-gray-100 shadow-sm">
|
|
10
10
|
<header
|
|
11
11
|
className={clsx(['py-8', 'px-4', 'mx-auto', 'container', 'md:px-0'])}
|
|
12
12
|
>
|
|
@@ -18,7 +18,7 @@ const PaymentStep = () => {
|
|
|
18
18
|
'pointer-events-none opacity-30': isPaymentStepBusy
|
|
19
19
|
})}
|
|
20
20
|
>
|
|
21
|
-
<div className="w-full mt-4 flex justify-start border border-gray-400 -mb-px z-10 md:mt-0 md:border-r-0 md:border-b-0 md:w-auto order-2 md:order-none">
|
|
21
|
+
<div className="w-full mt-4 flex justify-start border border-gray-400 -mb-px z-10 md:mt-0 md:border-r-0 md:border-b-0 md:w-auto order-2 md:order-none overflow-x-auto">
|
|
22
22
|
<PaymentOptionButtons />
|
|
23
23
|
</div>
|
|
24
24
|
<div className="w-full border border-solid border-gray-400 bg-white">
|
|
@@ -319,7 +319,7 @@ const CheckoutCreditCard = () => {
|
|
|
319
319
|
size={16}
|
|
320
320
|
className="leading-none ml-2"
|
|
321
321
|
/>
|
|
322
|
-
<div className="hidden group-hover:block absolute right-0 bottom-5 w-[11rem] lg:w-[21rem] lg:left-auto lg:right-auto border-2">
|
|
322
|
+
<div className="hidden group-hover:block absolute right-0 bottom-5 w-[11rem] lg:w-[21rem] lg:left-auto lg:right-auto border-2 border-gray-200">
|
|
323
323
|
{/* TODO: Fix this */}
|
|
324
324
|
<Image
|
|
325
325
|
src="/cvv.jpg"
|
|
@@ -44,7 +44,7 @@ const PaymentOptionButtons = () => {
|
|
|
44
44
|
{displayedPaymentOptions.map((option) => (
|
|
45
45
|
<label
|
|
46
46
|
key={`payment-option-${option.pk}`}
|
|
47
|
-
className="border px-4 py-3 mt-3 flex h-12"
|
|
47
|
+
className="border border-gray-200 px-4 py-3 mt-3 flex h-12"
|
|
48
48
|
onClick={scrollToTop}
|
|
49
49
|
>
|
|
50
50
|
<Radio
|
|
@@ -69,10 +69,10 @@ const PaymentOptionButtons = () => {
|
|
|
69
69
|
onClick={() => onClickHandler(option)}
|
|
70
70
|
className={clsx(
|
|
71
71
|
'flex items-center justify-center border-r border-b border-solid',
|
|
72
|
-
'border-gray-400 text-xs uppercase text-black-800 font-medium',
|
|
73
|
-
'
|
|
72
|
+
'border-gray-400 text-xs uppercase text-black-800/60 font-medium',
|
|
73
|
+
'bg-white h-11 px-5 transition-colors sm:h-15 sm:px-8 sm:py-8 hover:text-secondary',
|
|
74
74
|
{
|
|
75
|
-
'text-
|
|
75
|
+
'text-black-800/100 border-b-transparent':
|
|
76
76
|
preOrder?.payment_option?.pk === option.pk
|
|
77
77
|
}
|
|
78
78
|
)}
|
|
@@ -130,7 +130,7 @@ const AddressBox = ({
|
|
|
130
130
|
onClick={() => handleAddressClick(addressType, address)}
|
|
131
131
|
key={address.pk}
|
|
132
132
|
className={clsx(
|
|
133
|
-
'cursor-pointer relative w-full border shadow p-4 min-h-[8rem]',
|
|
133
|
+
'cursor-pointer relative w-full border border-gray-200 shadow-sm p-4 min-h-[8rem]',
|
|
134
134
|
"hover:after:content-[''] hover:after:border-4 hover:after:opacity-30 hover:after:transition-opacity",
|
|
135
135
|
'after:border-secondary-400 after:absolute after:inset-0 after:duration-150 after:-z-10',
|
|
136
136
|
{
|
|
@@ -167,7 +167,7 @@ const AddressBox = ({
|
|
|
167
167
|
<div className="text-xs flex justify-between">
|
|
168
168
|
<Button
|
|
169
169
|
appearance="ghost"
|
|
170
|
-
className="italic underline hover:text-secondary-500 hover
|
|
170
|
+
className="italic underline hover:text-secondary-500 hover:bg-white! hover:border-white! p-0 h-auto"
|
|
171
171
|
onClick={() => setIsEditAddressModalOpen(true)}
|
|
172
172
|
data-testid="checkout-address-edit"
|
|
173
173
|
>
|
|
@@ -193,7 +193,7 @@ const AddressBox = ({
|
|
|
193
193
|
</Modal>
|
|
194
194
|
<Button
|
|
195
195
|
appearance="ghost"
|
|
196
|
-
className="italic underline hover:text-secondary-500 hover
|
|
196
|
+
className="italic underline hover:text-secondary-500 hover:bg-white! hover:border-white! p-0 h-auto"
|
|
197
197
|
onClick={() => setRemoveAddressModalOpen(true)}
|
|
198
198
|
data-testid="checkout-address-remove"
|
|
199
199
|
>
|
|
@@ -153,7 +153,7 @@ const Addresses = () => {
|
|
|
153
153
|
role="button"
|
|
154
154
|
onClick={() => setIsModalOpen(true)}
|
|
155
155
|
className={clsx(
|
|
156
|
-
'relative cursor-pointer w-full min-h-[8rem] border shadow p-4',
|
|
156
|
+
'relative cursor-pointer w-full min-h-[8rem] border border-gray-200 shadow-sm p-4',
|
|
157
157
|
"hover:after:content-[''] hover:after:border-4 hover:after:opacity-30 hover:after:transition-opacity",
|
|
158
158
|
'after:border-secondary-400 after:absolute after:inset-0 after:opacity-0 after:duration-150 after:-z-10',
|
|
159
159
|
{
|
|
@@ -149,7 +149,7 @@ export const Summary = () => {
|
|
|
149
149
|
</div>
|
|
150
150
|
</div>
|
|
151
151
|
<div className="flex flex-col py-4 px-4 text-black-800 text-xs sm:px-5">
|
|
152
|
-
<div className="w-full overflow-hidden
|
|
152
|
+
<div className="w-full overflow-hidden text-ellipsis mb-1 last:mb-0">
|
|
153
153
|
<Trans
|
|
154
154
|
i18nKey="checkout.summary.info"
|
|
155
155
|
components={{
|
|
@@ -162,7 +162,7 @@ export const Summary = () => {
|
|
|
162
162
|
}}
|
|
163
163
|
/>
|
|
164
164
|
</div>
|
|
165
|
-
<div className="w-full overflow-hidden
|
|
165
|
+
<div className="w-full overflow-hidden text-ellipsis mb-1 last:mb-0">
|
|
166
166
|
{preOrder.shipping_address?.line}{' '}
|
|
167
167
|
{preOrder.shipping_address?.postcode}{' '}
|
|
168
168
|
{preOrder.shipping_address?.district && (
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { ReactNode, useMemo, useRef, useCallback } from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import { useGetMiniBasketQuery } from '@akinon/next/data/client/basket';
|
|
5
5
|
import { useAppDispatch, useAppSelector } from '@akinon/next/redux/hooks';
|
|
6
6
|
import {
|
|
7
7
|
closeMiniBasket,
|
|
@@ -29,8 +29,11 @@ interface MenuItem {
|
|
|
29
29
|
export default function ActionMenu() {
|
|
30
30
|
const dispatch = useAppDispatch();
|
|
31
31
|
|
|
32
|
-
const { data } =
|
|
33
|
-
const totalQuantity = useMemo(
|
|
32
|
+
const { data: miniBasket } = useGetMiniBasketQuery();
|
|
33
|
+
const totalQuantity = useMemo(
|
|
34
|
+
() => miniBasket?.total_quantity ?? 0,
|
|
35
|
+
[miniBasket]
|
|
36
|
+
);
|
|
34
37
|
|
|
35
38
|
const { open: miniBasketOpen } = useAppSelector(
|
|
36
39
|
(state) => state.root.miniBasket
|
|
@@ -16,13 +16,13 @@ export default function HeaderBand() {
|
|
|
16
16
|
</div>
|
|
17
17
|
|
|
18
18
|
<div className="header-grid-area-nav bg-gray-100 h-auto p-3 sm:header-grid-area-band-m sm:h-9 sm:py-0">
|
|
19
|
-
<div className="text-center
|
|
19
|
+
<div className="text-center text-ellipsis line-clamp-2 h-full flex items-center justify-center">
|
|
20
20
|
<HeaderBandText />
|
|
21
21
|
</div>
|
|
22
22
|
</div>
|
|
23
23
|
|
|
24
24
|
<div className="header-grid-area-main-r h-full pr-4 sm:header-grid-area-band-r sm:pr-0">
|
|
25
|
-
<div className="flex items-center justify-end h-full">
|
|
25
|
+
<div className="flex items-center justify-end h-full gap-10">
|
|
26
26
|
<UserMenu isMobile={false} />
|
|
27
27
|
<ActionMenu />
|
|
28
28
|
</div>
|