@windrun-huaiin/third-ui 10.1.1 → 10.1.3
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/clerk/clerk-user-client.js +1 -1
- package/dist/clerk/clerk-user-client.mjs +1 -1
- package/dist/clerk/fingerprint/fingerprint-client.js +2 -2
- package/dist/clerk/fingerprint/fingerprint-client.mjs +3 -3
- package/dist/clerk/fingerprint/fingerprint-shared.d.ts +1 -0
- package/dist/clerk/fingerprint/fingerprint-shared.js +2 -0
- package/dist/clerk/fingerprint/fingerprint-shared.mjs +2 -1
- package/dist/clerk/fingerprint/index.js +1 -0
- package/dist/clerk/fingerprint/index.mjs +1 -1
- package/dist/clerk/fingerprint/server.js +1 -0
- package/dist/clerk/fingerprint/server.mjs +1 -1
- package/dist/clerk/fingerprint/use-fingerprint.js +2 -1
- package/dist/clerk/fingerprint/use-fingerprint.mjs +2 -1
- package/dist/fuma/base/custom-header.d.ts +2 -2
- package/dist/fuma/base/custom-header.js +23 -4
- package/dist/fuma/base/custom-header.mjs +23 -4
- package/dist/main/credit/credit-nav-button.js +1 -1
- package/dist/main/credit/credit-nav-button.mjs +1 -1
- package/package.json +1 -1
- package/src/clerk/fingerprint/fingerprint-client.ts +3 -2
- package/src/clerk/fingerprint/fingerprint-shared.ts +1 -0
- package/src/clerk/fingerprint/use-fingerprint.ts +2 -0
- package/dist/main/gallery-interactive.d.ts +0 -18
- package/dist/main/gallery-interactive.js +0 -138
- package/dist/main/gallery-interactive.mjs +0 -136
- package/dist/main/gallery.d.ts +0 -7
- package/dist/main/gallery.js +0 -43
- package/dist/main/gallery.mjs +0 -41
|
@@ -7,7 +7,7 @@ var server = require('@windrun-huaiin/base-ui/components/server');
|
|
|
7
7
|
var signupButtonWithFingerprintClient = require('./signup-button-with-fingerprint-client.js');
|
|
8
8
|
|
|
9
9
|
function ClerkUserClient({ data }) {
|
|
10
|
-
return (jsxRuntime.jsxs("div", { className: "flex items-center gap-2 h-10
|
|
10
|
+
return (jsxRuntime.jsxs("div", { className: "flex items-center gap-2 h-10 mr-3 sm:mr-2", children: [jsxRuntime.jsx(nextjs.ClerkLoading, { children: jsxRuntime.jsx("div", { className: "w-20 h-9 px-2 border border-gray-300 rounded-full hover:bg-gray-100 dark:border-gray-600 dark:hover:bg-gray-800 text-center text-sm" }) }), jsxRuntime.jsxs(nextjs.ClerkLoaded, { children: [jsxRuntime.jsxs(nextjs.SignedOut, { children: [jsxRuntime.jsx(nextjs.SignInButton, { mode: data.clerkAuthInModal ? 'modal' : 'redirect', children: jsxRuntime.jsx("button", { className: "w-16 sm:w-20 h-8 sm:h-9 px-1.5 sm:px-2 border border-gray-300 rounded-full hover:bg-gray-100 dark:border-gray-600 dark:hover:bg-gray-800 text-center text-xs sm:text-sm whitespace-nowrap", children: data.signIn }) }), data.showSignUp && (jsxRuntime.jsx(signupButtonWithFingerprintClient.SignUpButtonWithFingerprint, { mode: data.clerkAuthInModal ? 'modal' : 'redirect', signUp: data.signUp }))] }), jsxRuntime.jsx(nextjs.SignedIn, { children: jsxRuntime.jsx(nextjs.UserButton, { appearance: {
|
|
11
11
|
elements: {
|
|
12
12
|
userButtonAvatarBox: "w-8 h-8 border",
|
|
13
13
|
}
|
|
@@ -5,7 +5,7 @@ import { globalLucideIcons } from '@windrun-huaiin/base-ui/components/server';
|
|
|
5
5
|
import { SignUpButtonWithFingerprint } from './signup-button-with-fingerprint-client.mjs';
|
|
6
6
|
|
|
7
7
|
function ClerkUserClient({ data }) {
|
|
8
|
-
return (jsxs("div", { className: "flex items-center gap-2 h-10
|
|
8
|
+
return (jsxs("div", { className: "flex items-center gap-2 h-10 mr-3 sm:mr-2", children: [jsx(ClerkLoading, { children: jsx("div", { className: "w-20 h-9 px-2 border border-gray-300 rounded-full hover:bg-gray-100 dark:border-gray-600 dark:hover:bg-gray-800 text-center text-sm" }) }), jsxs(ClerkLoaded, { children: [jsxs(SignedOut, { children: [jsx(SignInButton, { mode: data.clerkAuthInModal ? 'modal' : 'redirect', children: jsx("button", { className: "w-16 sm:w-20 h-8 sm:h-9 px-1.5 sm:px-2 border border-gray-300 rounded-full hover:bg-gray-100 dark:border-gray-600 dark:hover:bg-gray-800 text-center text-xs sm:text-sm whitespace-nowrap", children: data.signIn }) }), data.showSignUp && (jsx(SignUpButtonWithFingerprint, { mode: data.clerkAuthInModal ? 'modal' : 'redirect', signUp: data.signUp }))] }), jsx(SignedIn, { children: jsx(UserButton, { appearance: {
|
|
9
9
|
elements: {
|
|
10
10
|
userButtonAvatarBox: "w-8 h-8 border",
|
|
11
11
|
}
|
|
@@ -118,7 +118,7 @@ function createFingerprintHeaders() {
|
|
|
118
118
|
return tslib_es6.__awaiter(this, void 0, void 0, function* () {
|
|
119
119
|
const fingerprintId = yield getOrGenerateFingerprintId();
|
|
120
120
|
return {
|
|
121
|
-
FINGERPRINT_HEADER_NAME: fingerprintId,
|
|
121
|
+
[fingerprintShared.FINGERPRINT_HEADER_NAME]: fingerprintId,
|
|
122
122
|
};
|
|
123
123
|
});
|
|
124
124
|
}
|
|
@@ -134,7 +134,7 @@ function useFingerprintHeaders() {
|
|
|
134
134
|
function createFingerprintFetch() {
|
|
135
135
|
return (url, init) => tslib_es6.__awaiter(this, void 0, void 0, function* () {
|
|
136
136
|
const fingerprintHeaders = yield createFingerprintHeaders();
|
|
137
|
-
const headers = Object.assign(Object.assign({}, fingerprintHeaders), ((init === null || init === void 0 ? void 0 : init.headers) || {}));
|
|
137
|
+
const headers = Object.assign(Object.assign(Object.assign({}, fingerprintHeaders), { [fingerprintShared.FINGERPRINT_SOURCE_REFER]: document.referrer || '' }), ((init === null || init === void 0 ? void 0 : init.headers) || {}));
|
|
138
138
|
return fetch(url, Object.assign(Object.assign({}, init), { headers }));
|
|
139
139
|
});
|
|
140
140
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { __awaiter } from '../../node_modules/.pnpm/@rollup_plugin-typescript@12.1.4_rollup@4.46.2_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.mjs';
|
|
2
2
|
import index from '../../node_modules/.pnpm/@fingerprintjs_fingerprintjs@4.6.2/node_modules/@fingerprintjs/fingerprintjs/dist/fp.esm.mjs';
|
|
3
|
-
import { isValidFingerprintId, FINGERPRINT_STORAGE_KEY, FINGERPRINT_COOKIE_NAME } from './fingerprint-shared.mjs';
|
|
3
|
+
import { isValidFingerprintId, FINGERPRINT_STORAGE_KEY, FINGERPRINT_COOKIE_NAME, FINGERPRINT_HEADER_NAME, FINGERPRINT_SOURCE_REFER } from './fingerprint-shared.mjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Fingerprint Client Utilities
|
|
@@ -116,7 +116,7 @@ function createFingerprintHeaders() {
|
|
|
116
116
|
return __awaiter(this, void 0, void 0, function* () {
|
|
117
117
|
const fingerprintId = yield getOrGenerateFingerprintId();
|
|
118
118
|
return {
|
|
119
|
-
FINGERPRINT_HEADER_NAME: fingerprintId,
|
|
119
|
+
[FINGERPRINT_HEADER_NAME]: fingerprintId,
|
|
120
120
|
};
|
|
121
121
|
});
|
|
122
122
|
}
|
|
@@ -132,7 +132,7 @@ function useFingerprintHeaders() {
|
|
|
132
132
|
function createFingerprintFetch() {
|
|
133
133
|
return (url, init) => __awaiter(this, void 0, void 0, function* () {
|
|
134
134
|
const fingerprintHeaders = yield createFingerprintHeaders();
|
|
135
|
-
const headers = Object.assign(Object.assign({}, fingerprintHeaders), ((init === null || init === void 0 ? void 0 : init.headers) || {}));
|
|
135
|
+
const headers = Object.assign(Object.assign(Object.assign({}, fingerprintHeaders), { [FINGERPRINT_SOURCE_REFER]: document.referrer || '' }), ((init === null || init === void 0 ? void 0 : init.headers) || {}));
|
|
136
136
|
return fetch(url, Object.assign(Object.assign({}, init), { headers }));
|
|
137
137
|
});
|
|
138
138
|
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
export declare const FINGERPRINT_STORAGE_KEY = "__x_fingerprint_id";
|
|
6
6
|
export declare const FINGERPRINT_HEADER_NAME = "x-fingerprint-id-v8";
|
|
7
7
|
export declare const FINGERPRINT_COOKIE_NAME = "__x_fingerprint_id";
|
|
8
|
+
export declare const FINGERPRINT_SOURCE_REFER = "x-source-ref";
|
|
8
9
|
/**
|
|
9
10
|
* 验证fingerprint ID格式
|
|
10
11
|
* 可以在客户端和服务端使用
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
const FINGERPRINT_STORAGE_KEY = '__x_fingerprint_id';
|
|
9
9
|
const FINGERPRINT_HEADER_NAME = 'x-fingerprint-id-v8';
|
|
10
10
|
const FINGERPRINT_COOKIE_NAME = '__x_fingerprint_id';
|
|
11
|
+
const FINGERPRINT_SOURCE_REFER = 'x-source-ref';
|
|
11
12
|
/**
|
|
12
13
|
* 验证fingerprint ID格式
|
|
13
14
|
* 可以在客户端和服务端使用
|
|
@@ -31,5 +32,6 @@ const FINGERPRINT_CONSTANTS = {
|
|
|
31
32
|
exports.FINGERPRINT_CONSTANTS = FINGERPRINT_CONSTANTS;
|
|
32
33
|
exports.FINGERPRINT_COOKIE_NAME = FINGERPRINT_COOKIE_NAME;
|
|
33
34
|
exports.FINGERPRINT_HEADER_NAME = FINGERPRINT_HEADER_NAME;
|
|
35
|
+
exports.FINGERPRINT_SOURCE_REFER = FINGERPRINT_SOURCE_REFER;
|
|
34
36
|
exports.FINGERPRINT_STORAGE_KEY = FINGERPRINT_STORAGE_KEY;
|
|
35
37
|
exports.isValidFingerprintId = isValidFingerprintId;
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
const FINGERPRINT_STORAGE_KEY = '__x_fingerprint_id';
|
|
7
7
|
const FINGERPRINT_HEADER_NAME = 'x-fingerprint-id-v8';
|
|
8
8
|
const FINGERPRINT_COOKIE_NAME = '__x_fingerprint_id';
|
|
9
|
+
const FINGERPRINT_SOURCE_REFER = 'x-source-ref';
|
|
9
10
|
/**
|
|
10
11
|
* 验证fingerprint ID格式
|
|
11
12
|
* 可以在客户端和服务端使用
|
|
@@ -26,4 +27,4 @@ const FINGERPRINT_CONSTANTS = {
|
|
|
26
27
|
COOKIE_NAME: FINGERPRINT_COOKIE_NAME,
|
|
27
28
|
};
|
|
28
29
|
|
|
29
|
-
export { FINGERPRINT_CONSTANTS, FINGERPRINT_COOKIE_NAME, FINGERPRINT_HEADER_NAME, FINGERPRINT_STORAGE_KEY, isValidFingerprintId };
|
|
30
|
+
export { FINGERPRINT_CONSTANTS, FINGERPRINT_COOKIE_NAME, FINGERPRINT_HEADER_NAME, FINGERPRINT_SOURCE_REFER, FINGERPRINT_STORAGE_KEY, isValidFingerprintId };
|
|
@@ -11,6 +11,7 @@ var fingerprintProvider = require('./fingerprint-provider.js');
|
|
|
11
11
|
exports.FINGERPRINT_CONSTANTS = fingerprintShared.FINGERPRINT_CONSTANTS;
|
|
12
12
|
exports.FINGERPRINT_COOKIE_NAME = fingerprintShared.FINGERPRINT_COOKIE_NAME;
|
|
13
13
|
exports.FINGERPRINT_HEADER_NAME = fingerprintShared.FINGERPRINT_HEADER_NAME;
|
|
14
|
+
exports.FINGERPRINT_SOURCE_REFER = fingerprintShared.FINGERPRINT_SOURCE_REFER;
|
|
14
15
|
exports.FINGERPRINT_STORAGE_KEY = fingerprintShared.FINGERPRINT_STORAGE_KEY;
|
|
15
16
|
exports.isValidFingerprintId = fingerprintShared.isValidFingerprintId;
|
|
16
17
|
exports.clearFingerprintId = fingerprintClient.clearFingerprintId;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
export { FINGERPRINT_CONSTANTS, FINGERPRINT_COOKIE_NAME, FINGERPRINT_HEADER_NAME, FINGERPRINT_STORAGE_KEY, isValidFingerprintId } from './fingerprint-shared.mjs';
|
|
2
|
+
export { FINGERPRINT_CONSTANTS, FINGERPRINT_COOKIE_NAME, FINGERPRINT_HEADER_NAME, FINGERPRINT_SOURCE_REFER, FINGERPRINT_STORAGE_KEY, isValidFingerprintId } from './fingerprint-shared.mjs';
|
|
3
3
|
export { clearFingerprintId, createFingerprintFetch, createFingerprintHeaders, generateFingerprintId, getFingerprintId, getOrGenerateFingerprintId, setFingerprintId, useFingerprintHeaders } from './fingerprint-client.mjs';
|
|
4
4
|
export { useFingerprint } from './use-fingerprint.mjs';
|
|
5
5
|
export { FingerprintProvider, FingerprintStatus, useFingerprintContext, useFingerprintContextSafe, withFingerprint } from './fingerprint-provider.mjs';
|
|
@@ -8,6 +8,7 @@ var fingerprintServer = require('./fingerprint-server.js');
|
|
|
8
8
|
exports.FINGERPRINT_CONSTANTS = fingerprintShared.FINGERPRINT_CONSTANTS;
|
|
9
9
|
exports.FINGERPRINT_COOKIE_NAME = fingerprintShared.FINGERPRINT_COOKIE_NAME;
|
|
10
10
|
exports.FINGERPRINT_HEADER_NAME = fingerprintShared.FINGERPRINT_HEADER_NAME;
|
|
11
|
+
exports.FINGERPRINT_SOURCE_REFER = fingerprintShared.FINGERPRINT_SOURCE_REFER;
|
|
11
12
|
exports.FINGERPRINT_STORAGE_KEY = fingerprintShared.FINGERPRINT_STORAGE_KEY;
|
|
12
13
|
exports.isValidFingerprintId = fingerprintShared.isValidFingerprintId;
|
|
13
14
|
exports.extractFingerprintFromNextRequest = fingerprintServer.extractFingerprintFromNextRequest;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { FINGERPRINT_CONSTANTS, FINGERPRINT_COOKIE_NAME, FINGERPRINT_HEADER_NAME, FINGERPRINT_STORAGE_KEY, isValidFingerprintId } from './fingerprint-shared.mjs';
|
|
1
|
+
export { FINGERPRINT_CONSTANTS, FINGERPRINT_COOKIE_NAME, FINGERPRINT_HEADER_NAME, FINGERPRINT_SOURCE_REFER, FINGERPRINT_STORAGE_KEY, isValidFingerprintId } from './fingerprint-shared.mjs';
|
|
2
2
|
export { extractFingerprintFromNextRequest, extractFingerprintFromNextStores, extractFingerprintId, generateServerFingerprintId } from './fingerprint-server.mjs';
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
var tslib_es6 = require('../../node_modules/.pnpm/@rollup_plugin-typescript@12.1.4_rollup@4.46.2_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js');
|
|
5
5
|
var React = require('react');
|
|
6
6
|
var fingerprintClient = require('./fingerprint-client.js');
|
|
7
|
+
var fingerprintShared = require('./fingerprint-shared.js');
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Hook for managing fingerprint ID and anonymous user data
|
|
@@ -64,7 +65,7 @@ function useFingerprint(config) {
|
|
|
64
65
|
const fingerprintHeaders = yield fingerprintClient.createFingerprintHeaders();
|
|
65
66
|
const response = yield fetch(config.apiEndpoint, {
|
|
66
67
|
method: 'POST',
|
|
67
|
-
headers: Object.assign({ 'Content-Type': 'application/json' }, fingerprintHeaders),
|
|
68
|
+
headers: Object.assign({ 'Content-Type': 'application/json', [fingerprintShared.FINGERPRINT_SOURCE_REFER]: document.referrer || '' }, fingerprintHeaders),
|
|
68
69
|
body: JSON.stringify({ fingerprintId }),
|
|
69
70
|
});
|
|
70
71
|
if (!response.ok) {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { __awaiter } from '../../node_modules/.pnpm/@rollup_plugin-typescript@12.1.4_rollup@4.46.2_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.mjs';
|
|
3
3
|
import { useState, useCallback, useEffect } from 'react';
|
|
4
4
|
import { getOrGenerateFingerprintId, createFingerprintHeaders } from './fingerprint-client.mjs';
|
|
5
|
+
import { FINGERPRINT_SOURCE_REFER } from './fingerprint-shared.mjs';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Hook for managing fingerprint ID and anonymous user data
|
|
@@ -62,7 +63,7 @@ function useFingerprint(config) {
|
|
|
62
63
|
const fingerprintHeaders = yield createFingerprintHeaders();
|
|
63
64
|
const response = yield fetch(config.apiEndpoint, {
|
|
64
65
|
method: 'POST',
|
|
65
|
-
headers: Object.assign({ 'Content-Type': 'application/json' }, fingerprintHeaders),
|
|
66
|
+
headers: Object.assign({ 'Content-Type': 'application/json', [FINGERPRINT_SOURCE_REFER]: document.referrer || '' }, fingerprintHeaders),
|
|
66
67
|
body: JSON.stringify({ fingerprintId }),
|
|
67
68
|
});
|
|
68
69
|
if (!response.ok) {
|
|
@@ -47,7 +47,7 @@ export interface CustomHomeHeaderProps extends HomeLayoutProps {
|
|
|
47
47
|
*/
|
|
48
48
|
mobileMenuActionsOrder?: MobileMenuAction[];
|
|
49
49
|
}
|
|
50
|
-
export type DesktopAction = 'search' | 'theme' | 'i18n' | 'secondary';
|
|
50
|
+
export type DesktopAction = 'search' | 'theme' | 'i18n' | 'secondary' | 'github';
|
|
51
51
|
export type MobileBarAction = 'pinned' | 'search' | 'menu';
|
|
52
|
-
export type MobileMenuAction = 'secondary' | 'separator' | 'i18n' | 'theme';
|
|
52
|
+
export type MobileMenuAction = 'secondary' | 'github' | 'separator' | 'i18n' | 'theme';
|
|
53
53
|
export declare function CustomHomeHeader({ nav, i18n, links, githubUrl, themeSwitch, searchToggle, bannerHeight, headerHeight, maxContentWidth, navbarClassName, floating, desktopActionsOrder, mobileBarActionsOrder, mobileMenuActionsOrder, }: CustomHomeHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -45,6 +45,13 @@ function CustomHomeHeader({ nav = {}, i18n = false, links, githubUrl, themeSwitc
|
|
|
45
45
|
const primaryMenuItems = filteredMenuItems.filter((item) => !isSecondary(item));
|
|
46
46
|
const secondaryMenuItems = filteredMenuItems.filter(isSecondary);
|
|
47
47
|
const desktopSecondaryItems = navItems.filter(isSecondary);
|
|
48
|
+
const desktopActionsIncludeGithub = desktopActionsOrder.includes('github');
|
|
49
|
+
const githubDesktopItem = desktopActionsIncludeGithub
|
|
50
|
+
? desktopSecondaryItems.find((item) => isGithubItem(item, githubUrl))
|
|
51
|
+
: undefined;
|
|
52
|
+
const desktopSecondaryDisplayItems = desktopActionsIncludeGithub && githubDesktopItem
|
|
53
|
+
? desktopSecondaryItems.filter((item) => !isGithubItem(item, githubUrl))
|
|
54
|
+
: desktopSecondaryItems;
|
|
48
55
|
const desktopActionNodes = {
|
|
49
56
|
search: searchToggle$1.enabled !== false
|
|
50
57
|
? (_b = (_a = searchToggle$1.components) === null || _a === void 0 ? void 0 : _a.lg) !== null && _b !== void 0 ? _b : (jsxRuntime.jsx(searchToggle.LargeSearchToggle, { className: "w-full rounded-full ps-2.5 max-w-[240px]", hideIfDisabled: true }))
|
|
@@ -53,14 +60,23 @@ function CustomHomeHeader({ nav = {}, i18n = false, links, githubUrl, themeSwitc
|
|
|
53
60
|
? (_c = themeSwitch.component) !== null && _c !== void 0 ? _c : jsxRuntime.jsx(themeToggle.ThemeToggle, { mode: themeSwitch === null || themeSwitch === void 0 ? void 0 : themeSwitch.mode })
|
|
54
61
|
: null,
|
|
55
62
|
i18n: i18n ? (jsxRuntime.jsx(CompactLanguageToggle, { children: jsxRuntime.jsx(server.globalLucideIcons.Languages, { className: "size-5" }) })) : null,
|
|
56
|
-
secondary:
|
|
63
|
+
secondary: desktopSecondaryDisplayItems.length ? (jsxRuntime.jsx("ul", { className: "flex flex-row gap-2 items-center empty:hidden", children: desktopSecondaryDisplayItems.map((item, i) => (jsxRuntime.jsx(NavbarLinkItem, { item: item, className: cn.cn(item.type === 'icon' && [
|
|
57
64
|
'-mx-1',
|
|
58
65
|
i === 0 && 'ms-0',
|
|
59
|
-
i ===
|
|
66
|
+
i === desktopSecondaryDisplayItems.length - 1 && 'me-0',
|
|
60
67
|
]) }, i))) })) : null,
|
|
68
|
+
github: githubDesktopItem ? (jsxRuntime.jsx(NavbarLinkItem, { item: githubDesktopItem, className: cn.cn(githubDesktopItem.type === 'icon' && '-mx-1') })) : null,
|
|
61
69
|
};
|
|
70
|
+
const mobileMenuActionsIncludeGithub = mobileMenuActionsOrder.includes('github');
|
|
71
|
+
const githubMobileMenuItem = mobileMenuActionsIncludeGithub
|
|
72
|
+
? secondaryMenuItems.find((item) => isGithubItem(item, githubUrl))
|
|
73
|
+
: undefined;
|
|
74
|
+
const secondaryMenuDisplayItems = mobileMenuActionsIncludeGithub && githubMobileMenuItem
|
|
75
|
+
? secondaryMenuItems.filter((item) => !isGithubItem(item, githubUrl))
|
|
76
|
+
: secondaryMenuItems;
|
|
62
77
|
const mobileMenuActionNodes = {
|
|
63
|
-
secondary:
|
|
78
|
+
secondary: secondaryMenuDisplayItems.length ? (jsxRuntime.jsx(jsxRuntime.Fragment, { children: secondaryMenuDisplayItems.map((item, i) => (jsxRuntime.jsx(MenuLinkItem, { item: item, className: "-me-1.5" }, i))) })) : null,
|
|
79
|
+
github: githubMobileMenuItem ? (jsxRuntime.jsx(MenuLinkItem, { item: githubMobileMenuItem, className: "-me-1.5" })) : null,
|
|
64
80
|
separator: jsxRuntime.jsx("div", { role: "separator", className: "flex-1" }),
|
|
65
81
|
i18n: i18n ? (jsxRuntime.jsxs(CompactLanguageToggle, { children: [jsxRuntime.jsx(server.globalLucideIcons.Languages, { className: "size-5" }), jsxRuntime.jsx(languageToggle.LanguageToggleText, {}), jsxRuntime.jsx(server.globalLucideIcons.ChevronDown, { className: "size-3 text-fd-muted-foreground" })] })) : null,
|
|
66
82
|
theme: themeSwitch.enabled !== false
|
|
@@ -205,7 +221,7 @@ function CompactLanguageToggle(_a) {
|
|
|
205
221
|
throw new Error('Missing `<I18nProvider />`');
|
|
206
222
|
return (jsxRuntime.jsxs(popover.Popover, { children: [jsxRuntime.jsx(popover.PopoverTrigger, Object.assign({ "aria-label": context.text.chooseLanguage }, props, { className: cn.cn(button.buttonVariants({
|
|
207
223
|
color: 'ghost',
|
|
208
|
-
className: 'gap-1.5 py-1.5
|
|
224
|
+
className: 'gap-1.5 py-1.5 px-1',
|
|
209
225
|
}), props.className), children: props.children })), jsxRuntime.jsxs(popover.PopoverContent, { className: cn.cn('flex min-w-[150px] z-1001 flex-col overflow-x-hidden rounded-xl border bg-fd-popover/60 p-0 text-fd-popover-foreground backdrop-blur-lg', contentClassName), children: [jsxRuntime.jsx("p", { className: "mb-1 p-2 text-xs font-medium text-fd-muted-foreground", children: context.text.chooseLanguage }), context.locales.map((item) => (jsxRuntime.jsx("button", { type: "button", className: cn.cn('p-2 text-start text-sm', item.locale === context.locale
|
|
210
226
|
? 'bg-fd-primary/10 font-medium text-fd-primary'
|
|
211
227
|
: 'hover:bg-fd-accent hover:text-fd-accent-foreground'), onClick: () => {
|
|
@@ -213,6 +229,9 @@ function CompactLanguageToggle(_a) {
|
|
|
213
229
|
(_a = context.onChange) === null || _a === void 0 ? void 0 : _a.call(context, item.locale);
|
|
214
230
|
}, children: item.name }, item.locale)))] })] }));
|
|
215
231
|
}
|
|
232
|
+
function isGithubItem(item, githubUrl) {
|
|
233
|
+
return Boolean(githubUrl && item.type === 'icon' && item.url === githubUrl);
|
|
234
|
+
}
|
|
216
235
|
function isSecondary(item) {
|
|
217
236
|
if ('secondary' in item && item.secondary != null)
|
|
218
237
|
return item.secondary;
|
|
@@ -43,6 +43,13 @@ function CustomHomeHeader({ nav = {}, i18n = false, links, githubUrl, themeSwitc
|
|
|
43
43
|
const primaryMenuItems = filteredMenuItems.filter((item) => !isSecondary(item));
|
|
44
44
|
const secondaryMenuItems = filteredMenuItems.filter(isSecondary);
|
|
45
45
|
const desktopSecondaryItems = navItems.filter(isSecondary);
|
|
46
|
+
const desktopActionsIncludeGithub = desktopActionsOrder.includes('github');
|
|
47
|
+
const githubDesktopItem = desktopActionsIncludeGithub
|
|
48
|
+
? desktopSecondaryItems.find((item) => isGithubItem(item, githubUrl))
|
|
49
|
+
: undefined;
|
|
50
|
+
const desktopSecondaryDisplayItems = desktopActionsIncludeGithub && githubDesktopItem
|
|
51
|
+
? desktopSecondaryItems.filter((item) => !isGithubItem(item, githubUrl))
|
|
52
|
+
: desktopSecondaryItems;
|
|
46
53
|
const desktopActionNodes = {
|
|
47
54
|
search: searchToggle.enabled !== false
|
|
48
55
|
? (_b = (_a = searchToggle.components) === null || _a === void 0 ? void 0 : _a.lg) !== null && _b !== void 0 ? _b : (jsx(LargeSearchToggle, { className: "w-full rounded-full ps-2.5 max-w-[240px]", hideIfDisabled: true }))
|
|
@@ -51,14 +58,23 @@ function CustomHomeHeader({ nav = {}, i18n = false, links, githubUrl, themeSwitc
|
|
|
51
58
|
? (_c = themeSwitch.component) !== null && _c !== void 0 ? _c : jsx(ThemeToggle, { mode: themeSwitch === null || themeSwitch === void 0 ? void 0 : themeSwitch.mode })
|
|
52
59
|
: null,
|
|
53
60
|
i18n: i18n ? (jsx(CompactLanguageToggle, { children: jsx(globalLucideIcons.Languages, { className: "size-5" }) })) : null,
|
|
54
|
-
secondary:
|
|
61
|
+
secondary: desktopSecondaryDisplayItems.length ? (jsx("ul", { className: "flex flex-row gap-2 items-center empty:hidden", children: desktopSecondaryDisplayItems.map((item, i) => (jsx(NavbarLinkItem, { item: item, className: cn(item.type === 'icon' && [
|
|
55
62
|
'-mx-1',
|
|
56
63
|
i === 0 && 'ms-0',
|
|
57
|
-
i ===
|
|
64
|
+
i === desktopSecondaryDisplayItems.length - 1 && 'me-0',
|
|
58
65
|
]) }, i))) })) : null,
|
|
66
|
+
github: githubDesktopItem ? (jsx(NavbarLinkItem, { item: githubDesktopItem, className: cn(githubDesktopItem.type === 'icon' && '-mx-1') })) : null,
|
|
59
67
|
};
|
|
68
|
+
const mobileMenuActionsIncludeGithub = mobileMenuActionsOrder.includes('github');
|
|
69
|
+
const githubMobileMenuItem = mobileMenuActionsIncludeGithub
|
|
70
|
+
? secondaryMenuItems.find((item) => isGithubItem(item, githubUrl))
|
|
71
|
+
: undefined;
|
|
72
|
+
const secondaryMenuDisplayItems = mobileMenuActionsIncludeGithub && githubMobileMenuItem
|
|
73
|
+
? secondaryMenuItems.filter((item) => !isGithubItem(item, githubUrl))
|
|
74
|
+
: secondaryMenuItems;
|
|
60
75
|
const mobileMenuActionNodes = {
|
|
61
|
-
secondary:
|
|
76
|
+
secondary: secondaryMenuDisplayItems.length ? (jsx(Fragment, { children: secondaryMenuDisplayItems.map((item, i) => (jsx(MenuLinkItem, { item: item, className: "-me-1.5" }, i))) })) : null,
|
|
77
|
+
github: githubMobileMenuItem ? (jsx(MenuLinkItem, { item: githubMobileMenuItem, className: "-me-1.5" })) : null,
|
|
62
78
|
separator: jsx("div", { role: "separator", className: "flex-1" }),
|
|
63
79
|
i18n: i18n ? (jsxs(CompactLanguageToggle, { children: [jsx(globalLucideIcons.Languages, { className: "size-5" }), jsx(LanguageToggleText, {}), jsx(globalLucideIcons.ChevronDown, { className: "size-3 text-fd-muted-foreground" })] })) : null,
|
|
64
80
|
theme: themeSwitch.enabled !== false
|
|
@@ -203,7 +219,7 @@ function CompactLanguageToggle(_a) {
|
|
|
203
219
|
throw new Error('Missing `<I18nProvider />`');
|
|
204
220
|
return (jsxs(Popover, { children: [jsx(PopoverTrigger, Object.assign({ "aria-label": context.text.chooseLanguage }, props, { className: cn(buttonVariants({
|
|
205
221
|
color: 'ghost',
|
|
206
|
-
className: 'gap-1.5 py-1.5
|
|
222
|
+
className: 'gap-1.5 py-1.5 px-1',
|
|
207
223
|
}), props.className), children: props.children })), jsxs(PopoverContent, { className: cn('flex min-w-[150px] z-1001 flex-col overflow-x-hidden rounded-xl border bg-fd-popover/60 p-0 text-fd-popover-foreground backdrop-blur-lg', contentClassName), children: [jsx("p", { className: "mb-1 p-2 text-xs font-medium text-fd-muted-foreground", children: context.text.chooseLanguage }), context.locales.map((item) => (jsx("button", { type: "button", className: cn('p-2 text-start text-sm', item.locale === context.locale
|
|
208
224
|
? 'bg-fd-primary/10 font-medium text-fd-primary'
|
|
209
225
|
: 'hover:bg-fd-accent hover:text-fd-accent-foreground'), onClick: () => {
|
|
@@ -211,6 +227,9 @@ function CompactLanguageToggle(_a) {
|
|
|
211
227
|
(_a = context.onChange) === null || _a === void 0 ? void 0 : _a.call(context, item.locale);
|
|
212
228
|
}, children: item.name }, item.locale)))] })] }));
|
|
213
229
|
}
|
|
230
|
+
function isGithubItem(item, githubUrl) {
|
|
231
|
+
return Boolean(githubUrl && item.type === 'icon' && item.url === githubUrl);
|
|
232
|
+
}
|
|
214
233
|
function isSecondary(item) {
|
|
215
234
|
if ('secondary' in item && item.secondary != null)
|
|
216
235
|
return item.secondary;
|
|
@@ -106,7 +106,7 @@ function CreditNavButton({ locale, totalBalance, totalLabel, children, }) {
|
|
|
106
106
|
closePricingModal,
|
|
107
107
|
}), [closeMenu, isMobile, openPricingModal, closePricingModal]);
|
|
108
108
|
const isOnetimeModal = pricingModal.mode === 'onetime';
|
|
109
|
-
return (jsxRuntime.jsxs(CreditNavPopoverContext.Provider, { value: contextValue, children: [jsxRuntime.jsxs(ui.DropdownMenu, { modal: false, open: open, onOpenChange: setOpen, children: [jsxRuntime.jsx(ui.DropdownMenuTrigger, { asChild: true, children: jsxRuntime.jsxs("button", { type: "button", "aria-label": `${formattedBalance} ${totalLabel}`, className: utils.cn('group
|
|
109
|
+
return (jsxRuntime.jsxs(CreditNavPopoverContext.Provider, { value: contextValue, children: [jsxRuntime.jsxs(ui.DropdownMenu, { modal: false, open: open, onOpenChange: setOpen, children: [jsxRuntime.jsx(ui.DropdownMenuTrigger, { asChild: true, children: jsxRuntime.jsxs("button", { type: "button", "aria-label": `${formattedBalance} ${totalLabel}`, className: utils.cn('group mx-2 sm:mx-1 inline-flex items-center gap-2 rounded-full border border-slate-200 bg-white pl-2 pr-4 py-1.5 text-sm font-semibold text-slate-700 shadow-sm transition-all dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100', 'hover:border-transparent hover:bg-linear-to-r hover:from-purple-500/90 hover:to-pink-500/90 hover:text-white hover:shadow-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-purple-500 dark:hover:from-purple-500 dark:hover:to-pink-500'), ref: triggerRef, children: [jsxRuntime.jsx("span", { className: "flex h-6 w-6 items-center justify-center rounded-full bg-linear-to-br from-purple-400/20 to-pink-500/20 text-purple-600 transition-transform group-hover:scale-105 dark:text-purple-200", children: jsxRuntime.jsx(server.globalLucideIcons.Gem, { className: "h-3.5 w-3.5" }) }), jsxRuntime.jsxs("span", { className: "relative flex items-center", children: [jsxRuntime.jsx("span", { className: "text-base font-semibold leading-none", children: formattedBalance }), jsxRuntime.jsx("span", { className: "sr-only", children: ` ${totalLabel}` })] })] }) }), jsxRuntime.jsx(ui.DropdownMenuContent, { forceMount: true, sideOffset: 12, align: "end", className: "z-50 border-0 bg-transparent p-0 shadow-none mx-4 sm:mx-2 md:mx-1", children: jsxRuntime.jsx("div", { className: "w-[90vw] max-w-[90vw] max-h-[80vh] overflow-y-auto overflow-x-hidden rounded-3xl bg-transparent sm:w-[410px] sm:max-h-[90vh] sm:max-w-[95vw]", ref: contentRef, children: children }) })] }), pricingModal.modalMoneyPriceData && pricingModal.pricingContext ? (jsxRuntime.jsx(ui.AlertDialog, { open: pricingModal.open, onOpenChange: (open) => setPricingModal((prev) => (Object.assign(Object.assign({}, prev), { open }))), children: jsxRuntime.jsxs(ui.AlertDialogContent, { className: "mt-5 sm:mt-6 md:mt-10 lg:mt-15 w-[95vw] max-w-[1200px] overflow-hidden border border-slate-200 bg-white p-0 shadow-[0_32px_90px_rgba(15,23,42,0.25)] ring-1 ring-black/5 dark:border-white/12 dark:bg-[#0f1222] dark:shadow-[0_40px_120px_rgba(0,0,0,0.6)] dark:ring-white/10", children: [jsxRuntime.jsxs(ui.AlertDialogHeader, { className: "flex flex-row items-center justify-between border-b border-slate-200 px-6 pt-4 pb-1 dark:border-slate-800", children: [jsxRuntime.jsx(ui.AlertDialogTitle, { asChild: true, children: jsxRuntime.jsxs("div", { className: "flex flex-wrap items-baseline gap-3 text-slate-900 dark:text-white", children: [jsxRuntime.jsx("span", { className: "text-2xl font-semibold leading-tight", children: pricingModal.modalMoneyPriceData.title }), pricingModal.modalMoneyPriceData.subtitle ? (jsxRuntime.jsx("span", { className: "text-sm font-medium text-slate-500 dark:text-slate-300", children: pricingModal.modalMoneyPriceData.subtitle })) : null] }) }), jsxRuntime.jsx("button", { type: "button", className: "rounded-full p-2 text-gray-400 transition hover:bg-gray-400 hover:text-gray-400 dark:text-white/80 dark:hover:bg-white/80 dark:hover:text-white/80", onClick: closePricingModal, children: jsxRuntime.jsx(server.globalLucideIcons.X, { className: "h-6 w-6" }) })] }), jsxRuntime.jsx("div", { className: "max-h-[60vh] sm:max-h-[80vh] overflow-y-auto px-4 pt-2 pb-6", children: jsxRuntime.jsx("div", { className: "mx-auto w-full", children: jsxRuntime.jsx(moneyPriceInteractive.MoneyPriceInteractive, { data: pricingModal.modalMoneyPriceData, config: pricingModal.pricingContext.moneyPriceConfig, checkoutApiEndpoint: pricingModal.pricingContext.checkoutApiEndpoint, customerPortalApiEndpoint: pricingModal.pricingContext.customerPortalApiEndpoint, enableSubscriptionUpgrade: pricingModal.pricingContext.enableSubscriptionUpgrade, initialBillingType: isOnetimeModal ? 'onetime' : undefined, disableAutoDetectBilling: isOnetimeModal, initUserContext: pricingModal.pricingContext.initUserContext }, pricingModal.mode) }) })] }) })) : null] }));
|
|
110
110
|
}
|
|
111
111
|
const CreditNavPopoverContext = React.createContext(null);
|
|
112
112
|
function useCreditNavPopover() {
|
|
@@ -104,7 +104,7 @@ function CreditNavButton({ locale, totalBalance, totalLabel, children, }) {
|
|
|
104
104
|
closePricingModal,
|
|
105
105
|
}), [closeMenu, isMobile, openPricingModal, closePricingModal]);
|
|
106
106
|
const isOnetimeModal = pricingModal.mode === 'onetime';
|
|
107
|
-
return (jsxs(CreditNavPopoverContext.Provider, { value: contextValue, children: [jsxs(DropdownMenu, { modal: false, open: open, onOpenChange: setOpen, children: [jsx(DropdownMenuTrigger, { asChild: true, children: jsxs("button", { type: "button", "aria-label": `${formattedBalance} ${totalLabel}`, className: cn('group
|
|
107
|
+
return (jsxs(CreditNavPopoverContext.Provider, { value: contextValue, children: [jsxs(DropdownMenu, { modal: false, open: open, onOpenChange: setOpen, children: [jsx(DropdownMenuTrigger, { asChild: true, children: jsxs("button", { type: "button", "aria-label": `${formattedBalance} ${totalLabel}`, className: cn('group mx-2 sm:mx-1 inline-flex items-center gap-2 rounded-full border border-slate-200 bg-white pl-2 pr-4 py-1.5 text-sm font-semibold text-slate-700 shadow-sm transition-all dark:border-slate-700 dark:bg-slate-900 dark:text-slate-100', 'hover:border-transparent hover:bg-linear-to-r hover:from-purple-500/90 hover:to-pink-500/90 hover:text-white hover:shadow-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-purple-500 dark:hover:from-purple-500 dark:hover:to-pink-500'), ref: triggerRef, children: [jsx("span", { className: "flex h-6 w-6 items-center justify-center rounded-full bg-linear-to-br from-purple-400/20 to-pink-500/20 text-purple-600 transition-transform group-hover:scale-105 dark:text-purple-200", children: jsx(globalLucideIcons.Gem, { className: "h-3.5 w-3.5" }) }), jsxs("span", { className: "relative flex items-center", children: [jsx("span", { className: "text-base font-semibold leading-none", children: formattedBalance }), jsx("span", { className: "sr-only", children: ` ${totalLabel}` })] })] }) }), jsx(DropdownMenuContent, { forceMount: true, sideOffset: 12, align: "end", className: "z-50 border-0 bg-transparent p-0 shadow-none mx-4 sm:mx-2 md:mx-1", children: jsx("div", { className: "w-[90vw] max-w-[90vw] max-h-[80vh] overflow-y-auto overflow-x-hidden rounded-3xl bg-transparent sm:w-[410px] sm:max-h-[90vh] sm:max-w-[95vw]", ref: contentRef, children: children }) })] }), pricingModal.modalMoneyPriceData && pricingModal.pricingContext ? (jsx(AlertDialog, { open: pricingModal.open, onOpenChange: (open) => setPricingModal((prev) => (Object.assign(Object.assign({}, prev), { open }))), children: jsxs(AlertDialogContent, { className: "mt-5 sm:mt-6 md:mt-10 lg:mt-15 w-[95vw] max-w-[1200px] overflow-hidden border border-slate-200 bg-white p-0 shadow-[0_32px_90px_rgba(15,23,42,0.25)] ring-1 ring-black/5 dark:border-white/12 dark:bg-[#0f1222] dark:shadow-[0_40px_120px_rgba(0,0,0,0.6)] dark:ring-white/10", children: [jsxs(AlertDialogHeader, { className: "flex flex-row items-center justify-between border-b border-slate-200 px-6 pt-4 pb-1 dark:border-slate-800", children: [jsx(AlertDialogTitle, { asChild: true, children: jsxs("div", { className: "flex flex-wrap items-baseline gap-3 text-slate-900 dark:text-white", children: [jsx("span", { className: "text-2xl font-semibold leading-tight", children: pricingModal.modalMoneyPriceData.title }), pricingModal.modalMoneyPriceData.subtitle ? (jsx("span", { className: "text-sm font-medium text-slate-500 dark:text-slate-300", children: pricingModal.modalMoneyPriceData.subtitle })) : null] }) }), jsx("button", { type: "button", className: "rounded-full p-2 text-gray-400 transition hover:bg-gray-400 hover:text-gray-400 dark:text-white/80 dark:hover:bg-white/80 dark:hover:text-white/80", onClick: closePricingModal, children: jsx(globalLucideIcons.X, { className: "h-6 w-6" }) })] }), jsx("div", { className: "max-h-[60vh] sm:max-h-[80vh] overflow-y-auto px-4 pt-2 pb-6", children: jsx("div", { className: "mx-auto w-full", children: jsx(MoneyPriceInteractive, { data: pricingModal.modalMoneyPriceData, config: pricingModal.pricingContext.moneyPriceConfig, checkoutApiEndpoint: pricingModal.pricingContext.checkoutApiEndpoint, customerPortalApiEndpoint: pricingModal.pricingContext.customerPortalApiEndpoint, enableSubscriptionUpgrade: pricingModal.pricingContext.enableSubscriptionUpgrade, initialBillingType: isOnetimeModal ? 'onetime' : undefined, disableAutoDetectBilling: isOnetimeModal, initUserContext: pricingModal.pricingContext.initUserContext }, pricingModal.mode) }) })] }) })) : null] }));
|
|
108
108
|
}
|
|
109
109
|
const CreditNavPopoverContext = createContext(null);
|
|
110
110
|
function useCreditNavPopover() {
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import FingerprintJS from '@fingerprintjs/fingerprintjs';
|
|
8
|
-
import {
|
|
8
|
+
import { FINGERPRINT_COOKIE_NAME, FINGERPRINT_HEADER_NAME, FINGERPRINT_SOURCE_REFER, FINGERPRINT_STORAGE_KEY, isValidFingerprintId } from './fingerprint-shared';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* 检查浏览器存储(localStorage 和 cookie)中的指纹 ID
|
|
@@ -128,7 +128,7 @@ export async function getOrGenerateFingerprintId(): Promise<string> {
|
|
|
128
128
|
export async function createFingerprintHeaders(): Promise<Record<string, string>> {
|
|
129
129
|
const fingerprintId = await getOrGenerateFingerprintId();
|
|
130
130
|
return {
|
|
131
|
-
FINGERPRINT_HEADER_NAME: fingerprintId,
|
|
131
|
+
[FINGERPRINT_HEADER_NAME]: fingerprintId,
|
|
132
132
|
};
|
|
133
133
|
}
|
|
134
134
|
|
|
@@ -147,6 +147,7 @@ export function createFingerprintFetch() {
|
|
|
147
147
|
const fingerprintHeaders = await createFingerprintHeaders();
|
|
148
148
|
const headers = {
|
|
149
149
|
...fingerprintHeaders,
|
|
150
|
+
[FINGERPRINT_SOURCE_REFER]: document.referrer || '',
|
|
150
151
|
...(init?.headers || {}),
|
|
151
152
|
};
|
|
152
153
|
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
export const FINGERPRINT_STORAGE_KEY = '__x_fingerprint_id';
|
|
8
8
|
export const FINGERPRINT_HEADER_NAME = 'x-fingerprint-id-v8';
|
|
9
9
|
export const FINGERPRINT_COOKIE_NAME = '__x_fingerprint_id';
|
|
10
|
+
export const FINGERPRINT_SOURCE_REFER = 'x-source-ref';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* 验证fingerprint ID格式
|
|
@@ -12,6 +12,7 @@ import type {
|
|
|
12
12
|
XSubscription,
|
|
13
13
|
XUser
|
|
14
14
|
} from './types';
|
|
15
|
+
import { FINGERPRINT_SOURCE_REFER } from './fingerprint-shared'
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Hook for managing fingerprint ID and anonymous user data
|
|
@@ -77,6 +78,7 @@ export function useFingerprint(config: FingerprintConfig): UseFingerprintResult
|
|
|
77
78
|
method: 'POST',
|
|
78
79
|
headers: {
|
|
79
80
|
'Content-Type': 'application/json',
|
|
81
|
+
[FINGERPRINT_SOURCE_REFER]: document.referrer || '',
|
|
80
82
|
...fingerprintHeaders,
|
|
81
83
|
},
|
|
82
84
|
body: JSON.stringify({ fingerprintId }),
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
interface GalleryItem {
|
|
2
|
-
id: string;
|
|
3
|
-
url: string;
|
|
4
|
-
altMsg: string;
|
|
5
|
-
}
|
|
6
|
-
interface GalleryData {
|
|
7
|
-
titleL: string;
|
|
8
|
-
eyesOn: string;
|
|
9
|
-
titleR: string;
|
|
10
|
-
description: string;
|
|
11
|
-
items: GalleryItem[];
|
|
12
|
-
defaultImgUrl: string;
|
|
13
|
-
downloadPrefix: string;
|
|
14
|
-
}
|
|
15
|
-
export declare function GalleryInteractive({ data }: {
|
|
16
|
-
data: GalleryData;
|
|
17
|
-
}): null;
|
|
18
|
-
export {};
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
var tslib_es6 = require('../node_modules/.pnpm/@rollup_plugin-typescript@12.1.4_rollup@4.46.2_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js');
|
|
5
|
-
var React = require('react');
|
|
6
|
-
|
|
7
|
-
function GalleryInteractive({ data }) {
|
|
8
|
-
const [imageErrors, setImageErrors] = React.useState(new Set());
|
|
9
|
-
const [downloadingItems, setDownloadingItems] = React.useState(new Set());
|
|
10
|
-
// Get CDN proxy URL from environment
|
|
11
|
-
const cdnProxyUrl = process.env.NEXT_PUBLIC_STYLE_CDN_PROXY_URL;
|
|
12
|
-
React.useEffect(() => {
|
|
13
|
-
// Progressive enhancement: Add download functionality and error handling
|
|
14
|
-
data.items.forEach((item, index) => {
|
|
15
|
-
const downloadButton = document.querySelector(`[data-gallery-download="${item.id}"]`);
|
|
16
|
-
const imageElement = document.querySelector(`[data-gallery-image="${item.id}"]`);
|
|
17
|
-
if (downloadButton) {
|
|
18
|
-
const handleDownload = () => tslib_es6.__awaiter(this, void 0, void 0, function* () {
|
|
19
|
-
var _a;
|
|
20
|
-
// Prevent duplicate clicks
|
|
21
|
-
if (downloadingItems.has(item.id)) {
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
// Set download status
|
|
25
|
-
setDownloadingItems(prev => new Set(prev).add(item.id));
|
|
26
|
-
try {
|
|
27
|
-
if (!cdnProxyUrl) {
|
|
28
|
-
throw new Error('CDN proxy URL not configured');
|
|
29
|
-
}
|
|
30
|
-
// Use R2 proxy to download directly
|
|
31
|
-
const originalUrl = new URL(item.url);
|
|
32
|
-
const filename = originalUrl.pathname.substring(1);
|
|
33
|
-
// Build proxy download URL
|
|
34
|
-
const proxyUrl = `${cdnProxyUrl}/${encodeURIComponent(filename)}`;
|
|
35
|
-
// Extract file extension from URL
|
|
36
|
-
const urlExtension = (_a = item.url.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
37
|
-
let extension = '.webp';
|
|
38
|
-
if (urlExtension && ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'].includes(urlExtension)) {
|
|
39
|
-
extension = `.${urlExtension}`;
|
|
40
|
-
}
|
|
41
|
-
// Fetch file from proxy
|
|
42
|
-
const response = yield fetch(proxyUrl);
|
|
43
|
-
if (!response.ok) {
|
|
44
|
-
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
45
|
-
}
|
|
46
|
-
// Convert to blob
|
|
47
|
-
const blob = yield response.blob();
|
|
48
|
-
const blobUrl = URL.createObjectURL(blob);
|
|
49
|
-
// Create download link and trigger download
|
|
50
|
-
const a = document.createElement('a');
|
|
51
|
-
a.href = blobUrl;
|
|
52
|
-
a.download = `${data.downloadPrefix}-${index + 1}${extension}`;
|
|
53
|
-
a.style.display = 'none';
|
|
54
|
-
document.body.appendChild(a);
|
|
55
|
-
a.click();
|
|
56
|
-
// Clean up DOM elements and blob URL
|
|
57
|
-
setTimeout(() => {
|
|
58
|
-
document.body.removeChild(a);
|
|
59
|
-
URL.revokeObjectURL(blobUrl);
|
|
60
|
-
}, 100);
|
|
61
|
-
}
|
|
62
|
-
catch (error) {
|
|
63
|
-
console.error('Download failed:', error);
|
|
64
|
-
}
|
|
65
|
-
finally {
|
|
66
|
-
// Clear download status
|
|
67
|
-
setDownloadingItems(prev => {
|
|
68
|
-
const newSet = new Set(prev);
|
|
69
|
-
newSet.delete(item.id);
|
|
70
|
-
return newSet;
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
downloadButton.addEventListener('click', handleDownload);
|
|
75
|
-
}
|
|
76
|
-
if (imageElement) {
|
|
77
|
-
const handleImageError = () => {
|
|
78
|
-
setImageErrors(prev => new Set(prev).add(item.id));
|
|
79
|
-
// Update image src to default
|
|
80
|
-
imageElement.src = data.defaultImgUrl;
|
|
81
|
-
};
|
|
82
|
-
imageElement.addEventListener('error', handleImageError);
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
// Update download button states based on downloading status
|
|
86
|
-
const updateDownloadStates = () => {
|
|
87
|
-
data.items.forEach((item) => {
|
|
88
|
-
const downloadButton = document.querySelector(`[data-gallery-download="${item.id}"]`);
|
|
89
|
-
if (downloadButton) {
|
|
90
|
-
const isDownloading = downloadingItems.has(item.id);
|
|
91
|
-
if (isDownloading) {
|
|
92
|
-
downloadButton.disabled = true;
|
|
93
|
-
downloadButton.classList.add('bg-black/30', 'text-white/50');
|
|
94
|
-
downloadButton.classList.remove('bg-black/50', 'hover:bg-black/70', 'text-white/80', 'hover:text-white');
|
|
95
|
-
// Replace icon with spinner
|
|
96
|
-
downloadButton.innerHTML = `
|
|
97
|
-
<svg class="h-5 w-5 text-white animate-spin" fill="none" viewBox="0 0 24 24">
|
|
98
|
-
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
|
99
|
-
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
|
100
|
-
</svg>
|
|
101
|
-
`;
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
downloadButton.disabled = false;
|
|
105
|
-
downloadButton.classList.remove('bg-black/30', 'text-white/50');
|
|
106
|
-
downloadButton.classList.add('bg-black/50', 'hover:bg-black/70', 'text-white/80', 'hover:text-white');
|
|
107
|
-
// Reset to download icon
|
|
108
|
-
downloadButton.innerHTML = `
|
|
109
|
-
<svg class="h-5 w-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
110
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
|
111
|
-
</svg>
|
|
112
|
-
`;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
};
|
|
117
|
-
updateDownloadStates();
|
|
118
|
-
// Cleanup event listeners
|
|
119
|
-
return () => {
|
|
120
|
-
data.items.forEach((item) => {
|
|
121
|
-
var _a, _b;
|
|
122
|
-
const downloadButton = document.querySelector(`[data-gallery-download="${item.id}"]`);
|
|
123
|
-
const imageElement = document.querySelector(`[data-gallery-image="${item.id}"]`);
|
|
124
|
-
if (downloadButton) {
|
|
125
|
-
const newButton = downloadButton.cloneNode(true);
|
|
126
|
-
(_a = downloadButton.parentNode) === null || _a === void 0 ? void 0 : _a.replaceChild(newButton, downloadButton);
|
|
127
|
-
}
|
|
128
|
-
if (imageElement) {
|
|
129
|
-
const newImage = imageElement.cloneNode(true);
|
|
130
|
-
(_b = imageElement.parentNode) === null || _b === void 0 ? void 0 : _b.replaceChild(newImage, imageElement);
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
};
|
|
134
|
-
}, [data, downloadingItems, imageErrors, cdnProxyUrl]);
|
|
135
|
-
return null; // Progressive enhancement - no additional DOM rendering
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
exports.GalleryInteractive = GalleryInteractive;
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { __awaiter } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.1.4_rollup@4.46.2_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.mjs';
|
|
3
|
-
import { useState, useEffect } from 'react';
|
|
4
|
-
|
|
5
|
-
function GalleryInteractive({ data }) {
|
|
6
|
-
const [imageErrors, setImageErrors] = useState(new Set());
|
|
7
|
-
const [downloadingItems, setDownloadingItems] = useState(new Set());
|
|
8
|
-
// Get CDN proxy URL from environment
|
|
9
|
-
const cdnProxyUrl = process.env.NEXT_PUBLIC_STYLE_CDN_PROXY_URL;
|
|
10
|
-
useEffect(() => {
|
|
11
|
-
// Progressive enhancement: Add download functionality and error handling
|
|
12
|
-
data.items.forEach((item, index) => {
|
|
13
|
-
const downloadButton = document.querySelector(`[data-gallery-download="${item.id}"]`);
|
|
14
|
-
const imageElement = document.querySelector(`[data-gallery-image="${item.id}"]`);
|
|
15
|
-
if (downloadButton) {
|
|
16
|
-
const handleDownload = () => __awaiter(this, void 0, void 0, function* () {
|
|
17
|
-
var _a;
|
|
18
|
-
// Prevent duplicate clicks
|
|
19
|
-
if (downloadingItems.has(item.id)) {
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
// Set download status
|
|
23
|
-
setDownloadingItems(prev => new Set(prev).add(item.id));
|
|
24
|
-
try {
|
|
25
|
-
if (!cdnProxyUrl) {
|
|
26
|
-
throw new Error('CDN proxy URL not configured');
|
|
27
|
-
}
|
|
28
|
-
// Use R2 proxy to download directly
|
|
29
|
-
const originalUrl = new URL(item.url);
|
|
30
|
-
const filename = originalUrl.pathname.substring(1);
|
|
31
|
-
// Build proxy download URL
|
|
32
|
-
const proxyUrl = `${cdnProxyUrl}/${encodeURIComponent(filename)}`;
|
|
33
|
-
// Extract file extension from URL
|
|
34
|
-
const urlExtension = (_a = item.url.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
35
|
-
let extension = '.webp';
|
|
36
|
-
if (urlExtension && ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'].includes(urlExtension)) {
|
|
37
|
-
extension = `.${urlExtension}`;
|
|
38
|
-
}
|
|
39
|
-
// Fetch file from proxy
|
|
40
|
-
const response = yield fetch(proxyUrl);
|
|
41
|
-
if (!response.ok) {
|
|
42
|
-
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
43
|
-
}
|
|
44
|
-
// Convert to blob
|
|
45
|
-
const blob = yield response.blob();
|
|
46
|
-
const blobUrl = URL.createObjectURL(blob);
|
|
47
|
-
// Create download link and trigger download
|
|
48
|
-
const a = document.createElement('a');
|
|
49
|
-
a.href = blobUrl;
|
|
50
|
-
a.download = `${data.downloadPrefix}-${index + 1}${extension}`;
|
|
51
|
-
a.style.display = 'none';
|
|
52
|
-
document.body.appendChild(a);
|
|
53
|
-
a.click();
|
|
54
|
-
// Clean up DOM elements and blob URL
|
|
55
|
-
setTimeout(() => {
|
|
56
|
-
document.body.removeChild(a);
|
|
57
|
-
URL.revokeObjectURL(blobUrl);
|
|
58
|
-
}, 100);
|
|
59
|
-
}
|
|
60
|
-
catch (error) {
|
|
61
|
-
console.error('Download failed:', error);
|
|
62
|
-
}
|
|
63
|
-
finally {
|
|
64
|
-
// Clear download status
|
|
65
|
-
setDownloadingItems(prev => {
|
|
66
|
-
const newSet = new Set(prev);
|
|
67
|
-
newSet.delete(item.id);
|
|
68
|
-
return newSet;
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
downloadButton.addEventListener('click', handleDownload);
|
|
73
|
-
}
|
|
74
|
-
if (imageElement) {
|
|
75
|
-
const handleImageError = () => {
|
|
76
|
-
setImageErrors(prev => new Set(prev).add(item.id));
|
|
77
|
-
// Update image src to default
|
|
78
|
-
imageElement.src = data.defaultImgUrl;
|
|
79
|
-
};
|
|
80
|
-
imageElement.addEventListener('error', handleImageError);
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
// Update download button states based on downloading status
|
|
84
|
-
const updateDownloadStates = () => {
|
|
85
|
-
data.items.forEach((item) => {
|
|
86
|
-
const downloadButton = document.querySelector(`[data-gallery-download="${item.id}"]`);
|
|
87
|
-
if (downloadButton) {
|
|
88
|
-
const isDownloading = downloadingItems.has(item.id);
|
|
89
|
-
if (isDownloading) {
|
|
90
|
-
downloadButton.disabled = true;
|
|
91
|
-
downloadButton.classList.add('bg-black/30', 'text-white/50');
|
|
92
|
-
downloadButton.classList.remove('bg-black/50', 'hover:bg-black/70', 'text-white/80', 'hover:text-white');
|
|
93
|
-
// Replace icon with spinner
|
|
94
|
-
downloadButton.innerHTML = `
|
|
95
|
-
<svg class="h-5 w-5 text-white animate-spin" fill="none" viewBox="0 0 24 24">
|
|
96
|
-
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
|
97
|
-
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
|
98
|
-
</svg>
|
|
99
|
-
`;
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
downloadButton.disabled = false;
|
|
103
|
-
downloadButton.classList.remove('bg-black/30', 'text-white/50');
|
|
104
|
-
downloadButton.classList.add('bg-black/50', 'hover:bg-black/70', 'text-white/80', 'hover:text-white');
|
|
105
|
-
// Reset to download icon
|
|
106
|
-
downloadButton.innerHTML = `
|
|
107
|
-
<svg class="h-5 w-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
108
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
|
109
|
-
</svg>
|
|
110
|
-
`;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
};
|
|
115
|
-
updateDownloadStates();
|
|
116
|
-
// Cleanup event listeners
|
|
117
|
-
return () => {
|
|
118
|
-
data.items.forEach((item) => {
|
|
119
|
-
var _a, _b;
|
|
120
|
-
const downloadButton = document.querySelector(`[data-gallery-download="${item.id}"]`);
|
|
121
|
-
const imageElement = document.querySelector(`[data-gallery-image="${item.id}"]`);
|
|
122
|
-
if (downloadButton) {
|
|
123
|
-
const newButton = downloadButton.cloneNode(true);
|
|
124
|
-
(_a = downloadButton.parentNode) === null || _a === void 0 ? void 0 : _a.replaceChild(newButton, downloadButton);
|
|
125
|
-
}
|
|
126
|
-
if (imageElement) {
|
|
127
|
-
const newImage = imageElement.cloneNode(true);
|
|
128
|
-
(_b = imageElement.parentNode) === null || _b === void 0 ? void 0 : _b.replaceChild(newImage, imageElement);
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
};
|
|
132
|
-
}, [data, downloadingItems, imageErrors, cdnProxyUrl]);
|
|
133
|
-
return null; // Progressive enhancement - no additional DOM rendering
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
export { GalleryInteractive };
|
package/dist/main/gallery.d.ts
DELETED
package/dist/main/gallery.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var tslib_es6 = require('../node_modules/.pnpm/@rollup_plugin-typescript@12.1.4_rollup@4.46.2_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js');
|
|
4
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
-
var server = require('next-intl/server');
|
|
6
|
-
var utils = require('@windrun-huaiin/lib/utils');
|
|
7
|
-
var Image = require('next/image');
|
|
8
|
-
require('react');
|
|
9
|
-
require('@windrun-huaiin/base-ui/components/server');
|
|
10
|
-
require('./nprogress-bar.js');
|
|
11
|
-
require('@windrun-huaiin/base-ui/ui');
|
|
12
|
-
require('./rich-text-expert.js');
|
|
13
|
-
require('next/navigation');
|
|
14
|
-
var galleryInteractive = require('./gallery-interactive.js');
|
|
15
|
-
require('@clerk/nextjs');
|
|
16
|
-
require('./money-price/money-price-types.js');
|
|
17
|
-
require('next/link');
|
|
18
|
-
var swiperReact = require('../node_modules/.pnpm/swiper@12.0.3/node_modules/swiper/swiper-react.js');
|
|
19
|
-
var pagination = require('../node_modules/.pnpm/swiper@12.0.3/node_modules/swiper/modules/pagination.js');
|
|
20
|
-
var sectionLayout = require('./section-layout.js');
|
|
21
|
-
|
|
22
|
-
function Gallery(_a) {
|
|
23
|
-
return tslib_es6.__awaiter(this, arguments, void 0, function* ({ locale, sectionClassName, button }) {
|
|
24
|
-
const t = yield server.getTranslations({ locale, namespace: 'gallery' });
|
|
25
|
-
const galleryItems = t.raw('prompts');
|
|
26
|
-
const data = {
|
|
27
|
-
titleL: t('titleL'),
|
|
28
|
-
eyesOn: t('eyesOn'),
|
|
29
|
-
titleR: t('titleR'),
|
|
30
|
-
description: t('description'),
|
|
31
|
-
items: galleryItems.map((item, index) => ({
|
|
32
|
-
id: `gallery-item-${index}`,
|
|
33
|
-
url: item.url,
|
|
34
|
-
altMsg: item.altMsg
|
|
35
|
-
})),
|
|
36
|
-
defaultImgUrl: t.raw('defaultImgUrl'),
|
|
37
|
-
downloadPrefix: t('downloadPrefix')
|
|
38
|
-
};
|
|
39
|
-
return (jsxRuntime.jsxs("section", { id: "gallery", className: utils.cn(sectionLayout.responsiveSection, sectionClassName), children: [jsxRuntime.jsxs("h2", { className: "text-3xl md:text-4xl font-bold text-center mb-6", children: [data.titleL, " ", jsxRuntime.jsx("span", { className: "text-purple-500", children: data.eyesOn }), " ", data.titleR] }), jsxRuntime.jsx("p", { className: "text-center max-w-2xl mx-auto mb-16", children: data.description }), jsxRuntime.jsx("div", { className: "block sm:hidden", children: jsxRuntime.jsx(swiperReact.Swiper, { modules: [pagination], pagination: { clickable: true }, spaceBetween: 20, slidesPerView: 1, loop: true, className: "rounded-xl overflow-hidden", children: data.items.map((item, index) => (jsxRuntime.jsx(swiperReact.SwiperSlide, { children: jsxRuntime.jsxs("div", { className: "relative aspect-square bg-gray-100", children: [jsxRuntime.jsx(Image, { src: item.url, alt: item.altMsg, fill: true, className: "object-cover", "data-gallery-image": item.id }), jsxRuntime.jsx("button", { className: "absolute bottom-4 right-4 p-3 rounded-full bg-black/60 hover:bg-black/80 text-white transition-all z-10", "data-gallery-download": item.id, "aria-label": `Download ${item.altMsg}`, children: jsxRuntime.jsx("svg", { className: "h-6 w-6", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" }) }) })] }) }, item.id))) }) }), jsxRuntime.jsx("div", { className: "hidden sm:grid sm:grid-cols-2 lg:grid-cols-3 gap-6", children: data.items.map((item, index) => (jsxRuntime.jsxs("div", { className: "group relative overflow-hidden rounded-xl", "data-gallery-item": item.id, "data-gallery-index": index, children: [jsxRuntime.jsx(Image, { src: item.url, alt: item.altMsg, width: 600, height: 600, className: "w-full h-80 object-cover transition duration-300 group-hover:scale-105", "data-gallery-image": item.id }), jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-end justify-end p-4 opacity-0 group-hover:opacity-100 transition duration-300", children: jsxRuntime.jsx("button", { className: "p-2 rounded-full bg-black/50 hover:bg-black/70 text-white/80 hover:text-white transition-all duration-300", "data-gallery-download": item.id, "aria-label": `Download ${item.altMsg}`, children: jsxRuntime.jsx("svg", { className: "h-5 w-5 text-white", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" }) }) }) })] }, item.id))) }), button && (jsxRuntime.jsx("div", { className: "text-center mt-12", children: button })), jsxRuntime.jsx(galleryInteractive.GalleryInteractive, { data: data })] }));
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
exports.Gallery = Gallery;
|
package/dist/main/gallery.mjs
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { __awaiter } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.1.4_rollup@4.46.2_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.mjs';
|
|
2
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { getTranslations } from 'next-intl/server';
|
|
4
|
-
import { cn } from '@windrun-huaiin/lib/utils';
|
|
5
|
-
import Image from 'next/image';
|
|
6
|
-
import 'react';
|
|
7
|
-
import '@windrun-huaiin/base-ui/components/server';
|
|
8
|
-
import './nprogress-bar.mjs';
|
|
9
|
-
import '@windrun-huaiin/base-ui/ui';
|
|
10
|
-
import './rich-text-expert.mjs';
|
|
11
|
-
import 'next/navigation';
|
|
12
|
-
import { GalleryInteractive } from './gallery-interactive.mjs';
|
|
13
|
-
import '@clerk/nextjs';
|
|
14
|
-
import './money-price/money-price-types.mjs';
|
|
15
|
-
import 'next/link';
|
|
16
|
-
import { Swiper, SwiperSlide } from '../node_modules/.pnpm/swiper@12.0.3/node_modules/swiper/swiper-react.mjs';
|
|
17
|
-
import Pagination from '../node_modules/.pnpm/swiper@12.0.3/node_modules/swiper/modules/pagination.mjs';
|
|
18
|
-
import { responsiveSection } from './section-layout.mjs';
|
|
19
|
-
|
|
20
|
-
function Gallery(_a) {
|
|
21
|
-
return __awaiter(this, arguments, void 0, function* ({ locale, sectionClassName, button }) {
|
|
22
|
-
const t = yield getTranslations({ locale, namespace: 'gallery' });
|
|
23
|
-
const galleryItems = t.raw('prompts');
|
|
24
|
-
const data = {
|
|
25
|
-
titleL: t('titleL'),
|
|
26
|
-
eyesOn: t('eyesOn'),
|
|
27
|
-
titleR: t('titleR'),
|
|
28
|
-
description: t('description'),
|
|
29
|
-
items: galleryItems.map((item, index) => ({
|
|
30
|
-
id: `gallery-item-${index}`,
|
|
31
|
-
url: item.url,
|
|
32
|
-
altMsg: item.altMsg
|
|
33
|
-
})),
|
|
34
|
-
defaultImgUrl: t.raw('defaultImgUrl'),
|
|
35
|
-
downloadPrefix: t('downloadPrefix')
|
|
36
|
-
};
|
|
37
|
-
return (jsxs("section", { id: "gallery", className: cn(responsiveSection, sectionClassName), children: [jsxs("h2", { className: "text-3xl md:text-4xl font-bold text-center mb-6", children: [data.titleL, " ", jsx("span", { className: "text-purple-500", children: data.eyesOn }), " ", data.titleR] }), jsx("p", { className: "text-center max-w-2xl mx-auto mb-16", children: data.description }), jsx("div", { className: "block sm:hidden", children: jsx(Swiper, { modules: [Pagination], pagination: { clickable: true }, spaceBetween: 20, slidesPerView: 1, loop: true, className: "rounded-xl overflow-hidden", children: data.items.map((item, index) => (jsx(SwiperSlide, { children: jsxs("div", { className: "relative aspect-square bg-gray-100", children: [jsx(Image, { src: item.url, alt: item.altMsg, fill: true, className: "object-cover", "data-gallery-image": item.id }), jsx("button", { className: "absolute bottom-4 right-4 p-3 rounded-full bg-black/60 hover:bg-black/80 text-white transition-all z-10", "data-gallery-download": item.id, "aria-label": `Download ${item.altMsg}`, children: jsx("svg", { className: "h-6 w-6", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" }) }) })] }) }, item.id))) }) }), jsx("div", { className: "hidden sm:grid sm:grid-cols-2 lg:grid-cols-3 gap-6", children: data.items.map((item, index) => (jsxs("div", { className: "group relative overflow-hidden rounded-xl", "data-gallery-item": item.id, "data-gallery-index": index, children: [jsx(Image, { src: item.url, alt: item.altMsg, width: 600, height: 600, className: "w-full h-80 object-cover transition duration-300 group-hover:scale-105", "data-gallery-image": item.id }), jsx("div", { className: "absolute inset-0 flex items-end justify-end p-4 opacity-0 group-hover:opacity-100 transition duration-300", children: jsx("button", { className: "p-2 rounded-full bg-black/50 hover:bg-black/70 text-white/80 hover:text-white transition-all duration-300", "data-gallery-download": item.id, "aria-label": `Download ${item.altMsg}`, children: jsx("svg", { className: "h-5 w-5 text-white", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" }) }) }) })] }, item.id))) }), button && (jsx("div", { className: "text-center mt-12", children: button })), jsx(GalleryInteractive, { data: data })] }));
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export { Gallery };
|