@akinon/projectzero 2.0.0-beta.19 → 2.0.0-beta.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/CHANGELOG.md +9 -7
- package/app-template/CHANGELOG.md +251 -204
- package/app-template/akinon.json +1 -1
- package/app-template/package.json +28 -28
- package/app-template/public/amex.svg +12 -0
- package/app-template/public/apple-pay.svg +16 -0
- package/app-template/public/assets/images/product-placeholder-1.jpg +0 -0
- package/app-template/public/assets/images/product-placeholder-2.jpg +0 -0
- package/app-template/public/assets/images/product-placeholder-3.jpg +0 -0
- package/app-template/public/assets/images/product-placeholder-4.jpg +0 -0
- package/app-template/public/google-pay.svg +16 -0
- package/app-template/public/locales/en/account.json +6 -3
- package/app-template/public/locales/en/auth.json +6 -7
- package/app-template/public/locales/en/basket.json +6 -6
- package/app-template/public/locales/en/blog.json +7 -0
- package/app-template/public/locales/en/category.json +3 -1
- package/app-template/public/locales/en/checkout.json +5 -4
- package/app-template/public/locales/en/common.json +11 -2
- package/app-template/public/locales/en/forgot_password.json +6 -7
- package/app-template/public/locales/en/product.json +4 -3
- package/app-template/public/locales/tr/account.json +6 -3
- package/app-template/public/locales/tr/auth.json +16 -17
- package/app-template/public/locales/tr/basket.json +4 -4
- package/app-template/public/locales/tr/blog.json +7 -0
- package/app-template/public/locales/tr/category.json +3 -1
- package/app-template/public/locales/tr/checkout.json +39 -38
- package/app-template/public/locales/tr/common.json +10 -1
- package/app-template/public/locales/tr/forgot_password.json +12 -13
- package/app-template/public/locales/tr/product.json +1 -0
- package/app-template/public/logo.svg +3 -27
- package/app-template/public/mastercard.svg +14 -0
- package/app-template/public/promotion-banner.jpg +0 -0
- package/app-template/public/shop-pay.svg +12 -0
- package/app-template/public/visa.svg +12 -0
- package/app-template/src/app/[commerce]/[locale]/[currency]/blog/[slug]/page.tsx +118 -0
- package/app-template/src/app/[commerce]/[locale]/[currency]/pages/[slug]/page.tsx +15 -0
- package/app-template/src/app/api/theme-settings/route.ts +12 -0
- package/app-template/src/assets/fonts/pz-icon.css +211 -49
- package/app-template/src/assets/fonts/pz-icon.eot +0 -0
- package/app-template/src/assets/fonts/pz-icon.html +486 -0
- package/app-template/src/assets/fonts/pz-icon.scss +373 -49
- package/app-template/src/assets/fonts/pz-icon.svg +215 -53
- package/app-template/src/assets/fonts/pz-icon.ttf +0 -0
- package/app-template/src/assets/fonts/pz-icon.woff +0 -0
- package/app-template/src/assets/fonts/pz-icon.woff2 +0 -0
- package/app-template/src/assets/globals.scss +4 -0
- package/app-template/src/assets/icons/arrow-right.svg +3 -0
- package/app-template/src/assets/icons/cart.svg +4 -12
- package/app-template/src/assets/icons/check.svg +2 -18
- package/app-template/src/assets/icons/chevron-down.svg +2 -7
- package/app-template/src/assets/icons/delete.svg +3 -0
- package/app-template/src/assets/icons/facebook.svg +2 -8
- package/app-template/src/assets/icons/fav-off.svg +5 -0
- package/app-template/src/assets/icons/fav-on.svg +5 -0
- package/app-template/src/assets/icons/filter-and-sort.svg +3 -0
- package/app-template/src/assets/icons/heart.svg +3 -0
- package/app-template/src/assets/icons/instagram.svg +2 -13
- package/app-template/src/assets/icons/materials.svg +3 -0
- package/app-template/src/assets/icons/person.svg +4 -0
- package/app-template/src/assets/icons/pinterest.svg +5 -11
- package/app-template/src/assets/icons/ruler.svg +3 -0
- package/app-template/src/assets/icons/search.svg +8 -11
- package/app-template/src/assets/icons/share.svg +2 -9
- package/app-template/src/assets/icons/snapchat.svg +3 -0
- package/app-template/src/assets/icons/tiktok.svg +3 -0
- package/app-template/src/assets/icons/tumblr.svg +6 -0
- package/app-template/src/assets/icons/twitter.svg +2 -10
- package/app-template/src/assets/icons/vimeo.svg +3 -0
- package/app-template/src/assets/icons/youtube.svg +3 -0
- package/app-template/src/assets/icons/zoom.svg +8 -0
- package/app-template/src/components/accordion.tsx +33 -11
- package/app-template/src/components/action-tooltip.tsx +160 -0
- package/app-template/src/components/currency-select.tsx +149 -4
- package/app-template/src/components/icon.tsx +5 -6
- package/app-template/src/components/index.ts +4 -1
- package/app-template/src/components/language-select.tsx +88 -2
- package/app-template/src/components/pagination.tsx +132 -20
- package/app-template/src/components/quantity-input.tsx +63 -0
- package/app-template/src/components/quantity-selector.tsx +203 -0
- package/app-template/src/components/route-handler.tsx +50 -0
- package/app-template/src/components/select.tsx +89 -69
- package/app-template/src/components/types/index.ts +26 -0
- package/app-template/src/components/widget-content.tsx +323 -0
- package/app-template/src/data/server/theme.ts +70 -0
- package/app-template/src/hooks/use-fav-button.tsx +5 -2
- package/app-template/src/hooks/use-product-cart.ts +11 -8
- package/app-template/src/hooks/use-theme-settings.ts +42 -0
- package/app-template/src/lib/fonts.ts +149 -0
- package/app-template/src/settings.js +2 -2
- package/app-template/src/types/hookform-resolvers-yup.d.ts +28 -0
- package/app-template/src/types/widget.ts +169 -0
- package/app-template/src/utils/formatDate.ts +48 -0
- package/app-template/src/utils/styles.ts +71 -0
- package/app-template/src/views/account/contact-form.tsx +147 -130
- package/app-template/src/views/basket/basket-item.tsx +691 -107
- package/app-template/src/views/basket/basket-summary-context.tsx +560 -0
- package/app-template/src/views/basket/designer-context.tsx +617 -0
- package/app-template/src/views/basket/index.ts +2 -0
- package/app-template/src/views/basket/summary.tsx +496 -75
- package/app-template/src/views/breadcrumb/breadcrumb-client.tsx +190 -0
- package/app-template/src/views/breadcrumb/breadcrumb-registrar.tsx +286 -0
- package/app-template/src/views/breadcrumb/constants.ts +15 -0
- package/app-template/src/views/breadcrumb/index.tsx +127 -0
- package/app-template/src/views/breadcrumb.tsx +13 -38
- package/app-template/src/views/category/category-banner.tsx +4 -23
- package/app-template/src/views/category/category-header.tsx +289 -66
- package/app-template/src/views/category/category-info.tsx +173 -24
- package/app-template/src/views/category/filters/filter-item.tsx +138 -42
- package/app-template/src/views/category/filters/index.tsx +208 -48
- package/app-template/src/views/category/layout.tsx +7 -4
- package/app-template/src/views/category/native-widget-context.tsx +257 -0
- package/app-template/src/views/category/product-list-registrar.tsx +665 -0
- package/app-template/src/views/checkout/auth.tsx +64 -40
- package/app-template/src/views/checkout/checkout-address-registrar.tsx +254 -0
- package/app-template/src/views/checkout/checkout-buttons-registrar.tsx +183 -0
- package/app-template/src/views/checkout/checkout-delivery-method-registrar.tsx +259 -0
- package/app-template/src/views/checkout/checkout-payment-options-registrar.tsx +253 -0
- package/app-template/src/views/checkout/checkout-summary-registrar.tsx +183 -0
- package/app-template/src/views/checkout/constants.ts +5 -0
- package/app-template/src/views/checkout/index.tsx +5 -0
- package/app-template/src/views/checkout/layout/header.tsx +9 -5
- package/app-template/src/views/checkout/steps/payment/index.tsx +5 -2
- package/app-template/src/views/checkout/steps/payment/options/credit-card/index.tsx +72 -1
- package/app-template/src/views/checkout/steps/payment/options/masterpass-rest.tsx +15 -0
- package/app-template/src/views/checkout/steps/payment/options/saved-card.tsx +18 -0
- package/app-template/src/views/checkout/steps/payment/payment-option-buttons.tsx +171 -40
- package/app-template/src/views/checkout/steps/shipping/address-box.tsx +74 -12
- package/app-template/src/views/checkout/steps/shipping/addresses.tsx +128 -45
- package/app-template/src/views/checkout/steps/shipping/shipping-options.tsx +232 -27
- package/app-template/src/views/checkout/summary.tsx +303 -29
- package/app-template/src/views/footer/footer-app-banner-context.tsx +326 -0
- package/app-template/src/views/footer/footer-bottom-context.tsx +215 -0
- package/app-template/src/views/footer/footer-bottom-wrapper.tsx +74 -0
- package/app-template/src/views/footer/footer-layout-constants.ts +35 -0
- package/app-template/src/views/footer/footer-layout-registrar.tsx +342 -0
- package/app-template/src/views/footer/footer-layout-switcher.tsx +110 -0
- package/app-template/src/views/footer/footer-menu-context.tsx +211 -0
- package/app-template/src/views/footer/footer-native-widgets.tsx +60 -0
- package/app-template/src/views/footer/footer-social-context.tsx +254 -0
- package/app-template/src/views/footer/footer-subscription-context.tsx +210 -0
- package/app-template/src/views/footer/footer-utils.ts +43 -0
- package/app-template/src/views/footer/footer-value-props-context.tsx +326 -0
- package/app-template/src/views/footer/logo-settings.ts +183 -0
- package/app-template/src/views/footer/native-widget-config.ts +262 -0
- package/app-template/src/views/footer/subscription-settings.ts +122 -0
- package/app-template/src/views/footer/use-footer-logo.ts +162 -0
- package/app-template/src/views/footer.tsx +415 -13
- package/app-template/src/views/guest-login/index.tsx +62 -58
- package/app-template/src/views/header/action-menu.tsx +277 -45
- package/app-template/src/views/header/band.tsx +6 -21
- package/app-template/src/views/header/designer-context.tsx +261 -0
- package/app-template/src/views/header/header-announcement-registrar.tsx +267 -0
- package/app-template/src/views/header/header-client-wrapper.tsx +496 -0
- package/app-template/src/views/header/header-content.tsx +1026 -0
- package/app-template/src/views/header/header-currency-registrar.tsx +348 -0
- package/app-template/src/views/header/header-icons-context.tsx +262 -0
- package/app-template/src/views/header/header-language-registrar.tsx +348 -0
- package/app-template/src/views/header/header-layout-context.tsx +143 -0
- package/app-template/src/views/header/header-layout-registrar.tsx +658 -0
- package/app-template/src/views/header/header-logo-context.tsx +228 -0
- package/app-template/src/views/header/header-logo.tsx +118 -0
- package/app-template/src/views/header/header-mini-basket-context.tsx +524 -0
- package/app-template/src/views/header/header-search-registrar.tsx +511 -0
- package/app-template/src/views/header/header-text-slider-registrar.tsx +382 -0
- package/app-template/src/views/header/index.tsx +109 -47
- package/app-template/src/views/header/inline-search.tsx +262 -0
- package/app-template/src/views/header/mini-basket.tsx +819 -44
- package/app-template/src/views/header/mobile-hamburger-button.tsx +5 -8
- package/app-template/src/views/header/mobile-menu.tsx +12 -0
- package/app-template/src/views/header/navbar-menu-context.tsx +219 -0
- package/app-template/src/views/header/navbar.tsx +178 -111
- package/app-template/src/views/header/search/index.tsx +71 -32
- package/app-template/src/views/header/search/results.tsx +127 -65
- package/app-template/src/views/header/search/search-input.tsx +61 -0
- package/app-template/src/views/header/server-settings-parser.ts +1105 -0
- package/app-template/src/views/header/use-header-icons.ts +241 -0
- package/app-template/src/views/header/use-header-logo.ts +213 -0
- package/app-template/src/views/header/use-navbar-menu.ts +179 -0
- package/app-template/src/views/login/index.tsx +54 -46
- package/app-template/src/views/product/accordion-section.tsx +61 -0
- package/app-template/src/views/product/accordion-wrapper.tsx +135 -43
- package/app-template/src/views/product/custom-button-group.tsx +69 -0
- package/app-template/src/views/product/favorites-button-section.tsx +69 -0
- package/app-template/src/views/product/find-in-store-section.tsx +60 -0
- package/app-template/src/views/product/index.ts +1 -0
- package/app-template/src/views/product/layout.tsx +6 -5
- package/app-template/src/views/product/misc-buttons.tsx +339 -25
- package/app-template/src/views/product/price-wrapper.tsx +3 -29
- package/app-template/src/views/product/product-actions.tsx +137 -8
- package/app-template/src/views/product/product-info-section.tsx +140 -0
- package/app-template/src/views/product/product-info.tsx +69 -31
- package/app-template/src/views/product/product-share.tsx +13 -8
- package/app-template/src/views/product/product-variants.tsx +2 -2
- package/app-template/src/views/product/quantity-section.tsx +73 -0
- package/app-template/src/views/product/sale-tag.tsx +10 -0
- package/app-template/src/views/product/share-section.tsx +357 -0
- package/app-template/src/views/product/slider.tsx +117 -79
- package/app-template/src/views/product/variant.tsx +69 -41
- package/app-template/src/views/product/variants-section.tsx +126 -0
- package/app-template/src/views/product-detail/constants.ts +272 -0
- package/app-template/src/views/product-detail/index.ts +10 -0
- package/app-template/src/views/product-detail/product-detail-registrar.tsx +616 -0
- package/app-template/src/views/product-item/index.tsx +119 -46
- package/app-template/src/views/register/index.tsx +14 -25
- package/app-template/src/views/share/index.tsx +9 -6
- package/app-template/src/views/widgets/home-hero-slider-content.tsx +41 -39
- package/app-template/src/widgets/flatpages/about-us/index.tsx +78 -0
- package/app-template/src/widgets/flatpages/blog-list/index.tsx +129 -0
- package/app-template/src/widgets/footer-app-banner.tsx +444 -0
- package/app-template/src/widgets/footer-bottom.tsx +127 -0
- package/app-template/src/widgets/footer-menu-compact.tsx +238 -0
- package/app-template/src/widgets/footer-menu-two.tsx +298 -0
- package/app-template/src/widgets/footer-social-client.tsx +251 -0
- package/app-template/src/widgets/footer-social.tsx +47 -16
- package/app-template/src/widgets/footer-subscription/footer-subscription-form.tsx +17 -14
- package/app-template/src/widgets/footer-subscription/index.tsx +183 -17
- package/app-template/src/widgets/footer-value-props.tsx +201 -0
- package/app-template/src/widgets/index.ts +7 -0
- package/app-template/src/widgets/schemas/about-us.json +46 -0
- package/app-template/src/widgets/schemas/blog-list.json +37 -0
- package/app-template/src/widgets/schemas/blog.json +29 -0
- package/app-template/tailwind.config.js +18 -2
- package/package.json +1 -1
|
@@ -1,21 +1,423 @@
|
|
|
1
1
|
import 'server-only';
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import FooterInfo from '@theme/widgets/footer-info';
|
|
5
|
-
import FooterMenu from '@theme/widgets/footer-menu';
|
|
3
|
+
import FooterBottom from '@theme/widgets/footer-bottom';
|
|
6
4
|
import FooterSocial from '@theme/widgets/footer-social';
|
|
7
5
|
import FooterSubscription from '@theme/widgets/footer-subscription';
|
|
6
|
+
import FooterMenuTwo from '@theme/widgets/footer-menu-two';
|
|
7
|
+
import FooterMenuCompact from '@theme/widgets/footer-menu-compact';
|
|
8
|
+
import FooterAppBanner from '@theme/widgets/footer-app-banner';
|
|
9
|
+
import FooterValueProps from '@theme/widgets/footer-value-props';
|
|
10
|
+
import { getWidgetData } from '@akinon/next/data/server';
|
|
11
|
+
import { getThemeSettings } from '@theme/data/server/theme';
|
|
12
|
+
import FooterNativeWidgets from './footer/footer-native-widgets';
|
|
13
|
+
import FooterLayoutSwitcher from './footer/footer-layout-switcher';
|
|
14
|
+
import FooterLayoutRegistrar from './footer/footer-layout-registrar';
|
|
15
|
+
import FooterBottomWrapper from './footer/footer-bottom-wrapper';
|
|
16
|
+
import {
|
|
17
|
+
FOOTER_NATIVE_SECTIONS,
|
|
18
|
+
FOOTER_SUBSCRIPTION_SECTION_ID,
|
|
19
|
+
FOOTER_MENU_SECTION_ID,
|
|
20
|
+
FOOTER_SOCIAL_SECTION_ID,
|
|
21
|
+
FOOTER_BOTTOM_SECTION_ID,
|
|
22
|
+
FOOTER_APP_BANNER_SECTION_ID,
|
|
23
|
+
FOOTER_VALUE_PROPS_SECTION_ID,
|
|
24
|
+
FOOTER_SOCIAL_ICONS_BLOCK_ID,
|
|
25
|
+
type FooterNativeWidgetSection,
|
|
26
|
+
parseWidgetBlockAttributes
|
|
27
|
+
} from './footer/native-widget-config';
|
|
28
|
+
import { getFooterLogoInitialSettingsFromSections } from './footer/logo-settings';
|
|
29
|
+
import { FooterSubscriptionProvider } from './footer/footer-subscription-context';
|
|
30
|
+
import { FooterMenuProvider } from './footer/footer-menu-context';
|
|
31
|
+
import { FooterSocialProvider, type SocialIconItem } from './footer/footer-social-context';
|
|
32
|
+
import { FooterBottomProvider } from './footer/footer-bottom-context';
|
|
33
|
+
import { FooterAppBannerProvider } from './footer/footer-app-banner-context';
|
|
34
|
+
import { FooterValuePropsProvider } from './footer/footer-value-props-context';
|
|
35
|
+
import {
|
|
36
|
+
FOOTER_SUBSCRIPTION_DEFAULT_CONTENT,
|
|
37
|
+
getFooterSubscriptionInitialBlocks,
|
|
38
|
+
mergeFooterSubscriptionContent
|
|
39
|
+
} from './footer/subscription-settings';
|
|
40
|
+
import {
|
|
41
|
+
FOOTER_LAYOUT_SECTION_ID,
|
|
42
|
+
FOOTER_LAYOUT_WIDGET_SLUG,
|
|
43
|
+
FOOTER_LAYOUT_BLOCK_IDS,
|
|
44
|
+
type FooterLayoutType
|
|
45
|
+
} from './footer/footer-layout-constants';
|
|
46
|
+
|
|
47
|
+
// Block styles type for footer layout
|
|
48
|
+
type FooterBlockStyles = Record<string, Record<string, unknown>>;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Parse footer layout settings from widget data (server-side)
|
|
52
|
+
*/
|
|
53
|
+
function parseFooterLayoutSettings(
|
|
54
|
+
widgetData: { attributes?: Record<string, unknown> } | null
|
|
55
|
+
): { layout: FooterLayoutType; blockStyles: FooterBlockStyles } {
|
|
56
|
+
const defaultResult = { layout: 'default' as FooterLayoutType, blockStyles: {} };
|
|
57
|
+
|
|
58
|
+
if (!widgetData?.attributes) return defaultResult;
|
|
59
|
+
|
|
60
|
+
const result: { layout: FooterLayoutType; blockStyles: FooterBlockStyles } = {
|
|
61
|
+
layout: 'default',
|
|
62
|
+
blockStyles: {}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// Parse section-level properties (layout)
|
|
66
|
+
const sectionData = widgetData.attributes[FOOTER_LAYOUT_SECTION_ID];
|
|
67
|
+
if (sectionData) {
|
|
68
|
+
try {
|
|
69
|
+
const data =
|
|
70
|
+
typeof sectionData === 'string'
|
|
71
|
+
? JSON.parse(sectionData)
|
|
72
|
+
: typeof sectionData === 'object' && sectionData !== null && 'value' in sectionData
|
|
73
|
+
? JSON.parse((sectionData as { value: string }).value)
|
|
74
|
+
: null;
|
|
75
|
+
|
|
76
|
+
if (data?.properties?.layout) {
|
|
77
|
+
const layout = data.properties.layout;
|
|
78
|
+
result.layout = (typeof layout === 'object' ? layout.desktop : layout) as FooterLayoutType;
|
|
79
|
+
}
|
|
80
|
+
} catch {
|
|
81
|
+
// Ignore parse errors
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Parse block styles (MAIN_ROW, BOTTOM_ROW)
|
|
86
|
+
Object.values(FOOTER_LAYOUT_BLOCK_IDS).forEach((blockId) => {
|
|
87
|
+
const blockData = widgetData.attributes?.[blockId];
|
|
88
|
+
if (!blockData) return;
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
const data =
|
|
92
|
+
typeof blockData === 'string'
|
|
93
|
+
? JSON.parse(blockData)
|
|
94
|
+
: typeof blockData === 'object' && blockData !== null && 'value' in blockData
|
|
95
|
+
? JSON.parse((blockData as { value: string }).value)
|
|
96
|
+
: null;
|
|
97
|
+
|
|
98
|
+
if (data?.styles) {
|
|
99
|
+
// Convert responsive styles to flat styles (desktop first)
|
|
100
|
+
const flatStyles: Record<string, string> = {};
|
|
101
|
+
Object.entries(data.styles).forEach(([key, value]) => {
|
|
102
|
+
if (typeof value === 'object' && value !== null) {
|
|
103
|
+
const responsiveValue = value as Record<string, string>;
|
|
104
|
+
flatStyles[key] =
|
|
105
|
+
responsiveValue.desktop ||
|
|
106
|
+
responsiveValue.mobile ||
|
|
107
|
+
Object.values(responsiveValue)[0] ||
|
|
108
|
+
'';
|
|
109
|
+
} else if (typeof value === 'string') {
|
|
110
|
+
flatStyles[key] = value;
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
if (Object.keys(flatStyles).length > 0) {
|
|
115
|
+
result.blockStyles[blockId] = flatStyles;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
} catch {
|
|
119
|
+
// Ignore parse errors
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function getFooterMenuInitialBlocks(
|
|
127
|
+
sections: FooterNativeWidgetSection[]
|
|
128
|
+
): FooterNativeWidgetSection['blocks'] {
|
|
129
|
+
const menuSection = sections.find(
|
|
130
|
+
(s) => s.sectionId === FOOTER_MENU_SECTION_ID
|
|
131
|
+
);
|
|
132
|
+
return menuSection?.blocks ?? [];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function getFooterSocialInitialBlocks(
|
|
136
|
+
sections: FooterNativeWidgetSection[],
|
|
137
|
+
defaultIcons?: SocialIconItem[]
|
|
138
|
+
): FooterNativeWidgetSection['blocks'] {
|
|
139
|
+
const socialSection = sections.find(
|
|
140
|
+
(s) => s.sectionId === FOOTER_SOCIAL_SECTION_ID
|
|
141
|
+
);
|
|
142
|
+
const blocks = socialSection?.blocks ?? [];
|
|
143
|
+
|
|
144
|
+
// If we have default icons, merge them into the footer-social-icons block
|
|
145
|
+
if (defaultIcons?.length) {
|
|
146
|
+
return blocks.map((block) => {
|
|
147
|
+
if (block.id === FOOTER_SOCIAL_ICONS_BLOCK_ID) {
|
|
148
|
+
const existingIcons = (block.properties as Record<string, unknown>)?.icons;
|
|
149
|
+
// Only set default icons if no icons are already configured
|
|
150
|
+
if (!existingIcons || (Array.isArray(existingIcons) && existingIcons.length === 0)) {
|
|
151
|
+
return {
|
|
152
|
+
...block,
|
|
153
|
+
properties: {
|
|
154
|
+
...block.properties,
|
|
155
|
+
icons: defaultIcons
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return block;
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return blocks;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function getFooterBottomInitialBlocks(
|
|
168
|
+
sections: FooterNativeWidgetSection[]
|
|
169
|
+
): FooterNativeWidgetSection['blocks'] {
|
|
170
|
+
const bottomSection = sections.find(
|
|
171
|
+
(s) => s.sectionId === FOOTER_BOTTOM_SECTION_ID
|
|
172
|
+
);
|
|
173
|
+
return bottomSection?.blocks ?? [];
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function getFooterAppBannerInitialData(
|
|
177
|
+
sections: FooterNativeWidgetSection[]
|
|
178
|
+
): {
|
|
179
|
+
blocks: FooterNativeWidgetSection['blocks'];
|
|
180
|
+
properties: Record<string, unknown>;
|
|
181
|
+
styles: Record<string, unknown>;
|
|
182
|
+
} {
|
|
183
|
+
const section = sections.find(
|
|
184
|
+
(s) => s.sectionId === FOOTER_APP_BANNER_SECTION_ID
|
|
185
|
+
);
|
|
186
|
+
return {
|
|
187
|
+
blocks: section?.blocks ?? [],
|
|
188
|
+
properties: section?.sectionProperties ?? {},
|
|
189
|
+
styles: section?.sectionStyles ?? {}
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function getFooterValuePropsInitialData(
|
|
194
|
+
sections: FooterNativeWidgetSection[]
|
|
195
|
+
): {
|
|
196
|
+
blocks: FooterNativeWidgetSection['blocks'];
|
|
197
|
+
properties: Record<string, unknown>;
|
|
198
|
+
styles: Record<string, unknown>;
|
|
199
|
+
} {
|
|
200
|
+
const section = sections.find(
|
|
201
|
+
(s) => s.sectionId === FOOTER_VALUE_PROPS_SECTION_ID
|
|
202
|
+
);
|
|
203
|
+
return {
|
|
204
|
+
blocks: section?.blocks ?? [],
|
|
205
|
+
properties: section?.sectionProperties ?? {},
|
|
206
|
+
styles: section?.sectionStyles ?? {}
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
async function getFooterNativeWidgetSections() {
|
|
211
|
+
const sections = await Promise.all(
|
|
212
|
+
FOOTER_NATIVE_SECTIONS.map(async section => {
|
|
213
|
+
let widgetData: Awaited<ReturnType<typeof getWidgetData>> | null = null;
|
|
214
|
+
|
|
215
|
+
try {
|
|
216
|
+
widgetData = await getWidgetData({ slug: section.widgetSlug });
|
|
217
|
+
} catch {
|
|
218
|
+
widgetData = null;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const blocks = section.blocks.map(block => ({
|
|
222
|
+
...block,
|
|
223
|
+
...parseWidgetBlockAttributes(widgetData as { attributes?: Record<string, unknown> }, block.id)
|
|
224
|
+
}));
|
|
225
|
+
|
|
226
|
+
const sectionAttrs = parseWidgetBlockAttributes(
|
|
227
|
+
widgetData as { attributes?: Record<string, unknown> },
|
|
228
|
+
section.sectionId
|
|
229
|
+
);
|
|
230
|
+
|
|
231
|
+
return {
|
|
232
|
+
...section,
|
|
233
|
+
blocks,
|
|
234
|
+
sectionProperties: sectionAttrs.properties,
|
|
235
|
+
sectionStyles: sectionAttrs.styles
|
|
236
|
+
} satisfies FooterNativeWidgetSection;
|
|
237
|
+
})
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
return sections;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export default async function Footer() {
|
|
244
|
+
const [footerNativeSections, themeSettings, footerSubscriptionData, footerLayoutSettingsData] =
|
|
245
|
+
await Promise.all([
|
|
246
|
+
getFooterNativeWidgetSections(),
|
|
247
|
+
getThemeSettings(),
|
|
248
|
+
getWidgetData({ slug: 'footer-subscription' }),
|
|
249
|
+
getWidgetData({ slug: FOOTER_LAYOUT_WIDGET_SLUG }).catch(() => null)
|
|
250
|
+
]);
|
|
251
|
+
const { layout: initialFooterLayout, blockStyles: initialBlockStyles } = parseFooterLayoutSettings(footerLayoutSettingsData);
|
|
252
|
+
const fallbackLogoSrc = themeSettings.logo || '/logo.svg';
|
|
253
|
+
const initialFooterLogoSettings = getFooterLogoInitialSettingsFromSections(
|
|
254
|
+
footerNativeSections,
|
|
255
|
+
fallbackLogoSrc
|
|
256
|
+
);
|
|
257
|
+
const footerSubscriptionTitle =
|
|
258
|
+
(footerSubscriptionData?.attributes as Record<string, { value?: string }> | undefined)?.title?.value || '';
|
|
259
|
+
const footerSubscriptionDescription =
|
|
260
|
+
(footerSubscriptionData?.attributes as Record<string, { value?: string }> | undefined)?.description?.value || '';
|
|
261
|
+
const initialFooterSubscriptionBlocks = mergeFooterSubscriptionContent(
|
|
262
|
+
getFooterSubscriptionInitialBlocks(footerNativeSections),
|
|
263
|
+
{
|
|
264
|
+
title:
|
|
265
|
+
footerSubscriptionTitle ||
|
|
266
|
+
FOOTER_SUBSCRIPTION_DEFAULT_CONTENT.title,
|
|
267
|
+
description:
|
|
268
|
+
footerSubscriptionDescription ||
|
|
269
|
+
FOOTER_SUBSCRIPTION_DEFAULT_CONTENT.description
|
|
270
|
+
}
|
|
271
|
+
);
|
|
272
|
+
|
|
273
|
+
// Convert theme-config socialNetworks to SocialIconItem format for editor
|
|
274
|
+
// Must be calculated before getFooterSocialInitialBlocks to pass as default
|
|
275
|
+
const defaultSocialIcons: SocialIconItem[] = Object.entries(themeSettings.socialNetworks || {})
|
|
276
|
+
.filter(([, value]: [string, unknown]) => {
|
|
277
|
+
const v = value as { icon?: string };
|
|
278
|
+
return v.icon;
|
|
279
|
+
})
|
|
280
|
+
.map(([key, value]: [string, unknown]) => {
|
|
281
|
+
const v = value as { url?: string };
|
|
282
|
+
return {
|
|
283
|
+
icon: key,
|
|
284
|
+
link: v.url || '#',
|
|
285
|
+
size: 24,
|
|
286
|
+
color: undefined
|
|
287
|
+
};
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
const initialFooterSocialBlocks = getFooterSocialInitialBlocks(
|
|
291
|
+
footerNativeSections,
|
|
292
|
+
defaultSocialIcons
|
|
293
|
+
);
|
|
294
|
+
|
|
295
|
+
const footerNativeSectionsWithContent = footerNativeSections.map(
|
|
296
|
+
(section) => {
|
|
297
|
+
if (section.sectionId === FOOTER_SUBSCRIPTION_SECTION_ID) {
|
|
298
|
+
return { ...section, blocks: initialFooterSubscriptionBlocks };
|
|
299
|
+
}
|
|
300
|
+
if (section.sectionId === FOOTER_SOCIAL_SECTION_ID) {
|
|
301
|
+
return { ...section, blocks: initialFooterSocialBlocks };
|
|
302
|
+
}
|
|
303
|
+
if (section.sectionId === FOOTER_APP_BANNER_SECTION_ID) {
|
|
304
|
+
return section; // App Banner blocks come from FOOTER_NATIVE_SECTIONS
|
|
305
|
+
}
|
|
306
|
+
if (section.sectionId === FOOTER_VALUE_PROPS_SECTION_ID) {
|
|
307
|
+
return section; // Value Props blocks come from FOOTER_NATIVE_SECTIONS
|
|
308
|
+
}
|
|
309
|
+
return section;
|
|
310
|
+
}
|
|
311
|
+
);
|
|
312
|
+
const initialFooterMenuBlocks = getFooterMenuInitialBlocks(
|
|
313
|
+
footerNativeSectionsWithContent
|
|
314
|
+
);
|
|
315
|
+
const initialFooterBottomBlocks = getFooterBottomInitialBlocks(
|
|
316
|
+
footerNativeSectionsWithContent
|
|
317
|
+
);
|
|
318
|
+
const initialAppBannerData = getFooterAppBannerInitialData(
|
|
319
|
+
footerNativeSectionsWithContent
|
|
320
|
+
);
|
|
321
|
+
const initialValuePropsData = getFooterValuePropsInitialData(
|
|
322
|
+
footerNativeSectionsWithContent
|
|
323
|
+
);
|
|
8
324
|
|
|
9
|
-
export default function Footer() {
|
|
10
325
|
return (
|
|
11
|
-
<
|
|
12
|
-
<
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
326
|
+
<footer className="px-4 pt-16 border-t border-[#d0d0d0] lg:px-0">
|
|
327
|
+
<FooterNativeWidgets sections={footerNativeSectionsWithContent} />
|
|
328
|
+
|
|
329
|
+
<FooterValuePropsProvider
|
|
330
|
+
initialBlocks={initialValuePropsData.blocks}
|
|
331
|
+
initialProperties={initialValuePropsData.properties}
|
|
332
|
+
initialStyles={initialValuePropsData.styles}
|
|
333
|
+
>
|
|
334
|
+
<FooterValueProps renderPosition="footer-top" />
|
|
335
|
+
</FooterValuePropsProvider>
|
|
336
|
+
|
|
337
|
+
<FooterAppBannerProvider
|
|
338
|
+
initialBlocks={initialAppBannerData.blocks}
|
|
339
|
+
initialProperties={initialAppBannerData.properties}
|
|
340
|
+
initialStyles={initialAppBannerData.styles}
|
|
341
|
+
>
|
|
342
|
+
<FooterAppBanner renderPosition="footer-top" />
|
|
343
|
+
</FooterAppBannerProvider>
|
|
344
|
+
|
|
345
|
+
<FooterLayoutRegistrar
|
|
346
|
+
initialLayout={initialFooterLayout}
|
|
347
|
+
initialBlockStyles={initialBlockStyles}
|
|
348
|
+
>
|
|
349
|
+
<FooterLayoutSwitcher
|
|
350
|
+
defaultLayout={
|
|
351
|
+
<>
|
|
352
|
+
<FooterMenuProvider initialBlocks={initialFooterMenuBlocks}>
|
|
353
|
+
<FooterMenuTwo
|
|
354
|
+
fallbackLogoSrc={fallbackLogoSrc}
|
|
355
|
+
initialLogoSettings={initialFooterLogoSettings}
|
|
356
|
+
/>
|
|
357
|
+
</FooterMenuProvider>
|
|
358
|
+
<div className="container flex flex-col py-16 gap-10 lg:items-center lg:justify-between lg:flex-row">
|
|
359
|
+
<FooterSubscriptionProvider
|
|
360
|
+
initialBlocks={initialFooterSubscriptionBlocks}
|
|
361
|
+
>
|
|
362
|
+
<FooterSubscription
|
|
363
|
+
title={footerSubscriptionTitle}
|
|
364
|
+
description={footerSubscriptionDescription}
|
|
365
|
+
/>
|
|
366
|
+
</FooterSubscriptionProvider>
|
|
367
|
+
<FooterSocialProvider initialBlocks={initialFooterSocialBlocks} defaultIcons={defaultSocialIcons}>
|
|
368
|
+
<FooterSocial />
|
|
369
|
+
</FooterSocialProvider>
|
|
370
|
+
</div>
|
|
371
|
+
</>
|
|
372
|
+
}
|
|
373
|
+
compactLayout={
|
|
374
|
+
<div className="container flex flex-col lg:flex-row gap-10 lg:gap-16 py-8">
|
|
375
|
+
{/* Menu on the left - takes more space */}
|
|
376
|
+
<div className="flex-1 lg:flex-[2]">
|
|
377
|
+
<FooterMenuProvider initialBlocks={initialFooterMenuBlocks}>
|
|
378
|
+
<FooterMenuCompact />
|
|
379
|
+
</FooterMenuProvider>
|
|
380
|
+
</div>
|
|
381
|
+
|
|
382
|
+
{/* Subscription + Social stacked on the right */}
|
|
383
|
+
<div className="flex flex-col gap-8 lg:flex-1">
|
|
384
|
+
<FooterSubscriptionProvider
|
|
385
|
+
initialBlocks={initialFooterSubscriptionBlocks}
|
|
386
|
+
>
|
|
387
|
+
<FooterSubscription
|
|
388
|
+
title={footerSubscriptionTitle}
|
|
389
|
+
description={footerSubscriptionDescription}
|
|
390
|
+
/>
|
|
391
|
+
</FooterSubscriptionProvider>
|
|
392
|
+
<FooterSocialProvider initialBlocks={initialFooterSocialBlocks} defaultIcons={defaultSocialIcons}>
|
|
393
|
+
<FooterSocial />
|
|
394
|
+
</FooterSocialProvider>
|
|
395
|
+
</div>
|
|
396
|
+
</div>
|
|
397
|
+
}
|
|
398
|
+
/>
|
|
399
|
+
<FooterBottomWrapper>
|
|
400
|
+
<FooterBottomProvider initialBlocks={initialFooterBottomBlocks}>
|
|
401
|
+
<FooterBottom />
|
|
402
|
+
</FooterBottomProvider>
|
|
403
|
+
</FooterBottomWrapper>
|
|
404
|
+
</FooterLayoutRegistrar>
|
|
405
|
+
|
|
406
|
+
<FooterValuePropsProvider
|
|
407
|
+
initialBlocks={initialValuePropsData.blocks}
|
|
408
|
+
initialProperties={initialValuePropsData.properties}
|
|
409
|
+
initialStyles={initialValuePropsData.styles}
|
|
410
|
+
>
|
|
411
|
+
<FooterValueProps renderPosition="footer-bottom" />
|
|
412
|
+
</FooterValuePropsProvider>
|
|
413
|
+
|
|
414
|
+
<FooterAppBannerProvider
|
|
415
|
+
initialBlocks={initialAppBannerData.blocks}
|
|
416
|
+
initialProperties={initialAppBannerData.properties}
|
|
417
|
+
initialStyles={initialAppBannerData.styles}
|
|
418
|
+
>
|
|
419
|
+
<FooterAppBanner renderPosition="footer-bottom" />
|
|
420
|
+
</FooterAppBannerProvider>
|
|
421
|
+
</footer>
|
|
20
422
|
);
|
|
21
423
|
}
|
|
@@ -62,68 +62,72 @@ const GuestLogin = () => {
|
|
|
62
62
|
};
|
|
63
63
|
|
|
64
64
|
return (
|
|
65
|
-
<
|
|
66
|
-
<
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
65
|
+
<section className="w-full mt-6 lg:mt-8">
|
|
66
|
+
<form onSubmit={handleSubmit(onSubmit)}>
|
|
67
|
+
<div>
|
|
68
|
+
<Input
|
|
69
|
+
labelStyle="floating"
|
|
70
|
+
label={t('checkout.auth.form.login.email.placeholder')}
|
|
71
|
+
name="email"
|
|
72
|
+
className="h-12"
|
|
73
|
+
{...register('user_email')}
|
|
74
|
+
error={errors.user_email}
|
|
75
|
+
data-testid="guest-email"
|
|
76
|
+
required
|
|
77
|
+
/>
|
|
78
|
+
</div>
|
|
78
79
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
80
|
+
<div className="mt-4">
|
|
81
|
+
<Input
|
|
82
|
+
labelStyle="floating"
|
|
83
|
+
label={t('checkout.auth.form.login.phone.placeholder')}
|
|
84
|
+
className="h-12"
|
|
85
|
+
name="phone_number"
|
|
86
|
+
type="tel"
|
|
87
|
+
format={user_phone_format.replace(/\9/g, '#')}
|
|
88
|
+
mask="_"
|
|
89
|
+
control={control}
|
|
90
|
+
{...register('phone_number')}
|
|
91
|
+
error={errors.phone_number}
|
|
92
|
+
data-testid="guest-phone"
|
|
93
|
+
required
|
|
94
|
+
/>
|
|
95
|
+
</div>
|
|
95
96
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
>
|
|
101
|
-
{t('checkout.auth.form.login.button')}
|
|
102
|
-
</Button>
|
|
103
|
-
|
|
104
|
-
<div className="text-sm text-black-400 md:text-xs">
|
|
105
|
-
<p className="mb-4">{t('checkout.auth.form.login.agreement.label')}</p>
|
|
106
|
-
<Checkbox
|
|
107
|
-
name="sms_allowed"
|
|
108
|
-
className={clsx('underline', errors.sms_allowed ? 'mb-8' : 'mb-4')}
|
|
109
|
-
{...register('sms_allowed')}
|
|
110
|
-
error={errors.sms_allowed}
|
|
111
|
-
data-testid="guest-sms"
|
|
97
|
+
<Button
|
|
98
|
+
type="submit"
|
|
99
|
+
className="w-full h-12 uppercase text-xs font-semibold mt-[38px]"
|
|
100
|
+
data-testid="guest-submit"
|
|
112
101
|
>
|
|
113
|
-
{t('checkout.auth.form.login.
|
|
114
|
-
</
|
|
102
|
+
{t('checkout.auth.form.login.button')}
|
|
103
|
+
</Button>
|
|
115
104
|
|
|
116
|
-
<
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
105
|
+
<div className="mt-[38px] text-sm text-black-400 md:text-xs">
|
|
106
|
+
<p className="mb-4">
|
|
107
|
+
{t('checkout.auth.form.login.agreement.label')}
|
|
108
|
+
</p>
|
|
109
|
+
<Checkbox
|
|
110
|
+
name="sms_allowed"
|
|
111
|
+
className="underline"
|
|
112
|
+
{...register('sms_allowed')}
|
|
113
|
+
error={errors.sms_allowed}
|
|
114
|
+
data-testid="guest-sms"
|
|
115
|
+
>
|
|
116
|
+
{t('checkout.auth.form.login.agreement.terms_conditions')}
|
|
117
|
+
</Checkbox>
|
|
118
|
+
|
|
119
|
+
<Checkbox
|
|
120
|
+
name="confirm"
|
|
121
|
+
className="underline mt-4"
|
|
122
|
+
{...register('kvkk_confirm')}
|
|
123
|
+
error={errors.kvkk_confirm}
|
|
124
|
+
data-testid="guest-kvkk"
|
|
125
|
+
>
|
|
126
|
+
{t('checkout.auth.form.login.agreement.privacy_policy')}
|
|
127
|
+
</Checkbox>
|
|
128
|
+
</div>
|
|
129
|
+
</form>
|
|
130
|
+
</section>
|
|
127
131
|
);
|
|
128
132
|
};
|
|
129
133
|
|