@wix/ditto-codegen-public 1.0.48 → 1.0.50
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/examples-apps/event-countdown/README.md +13 -0
- package/dist/examples-apps/event-countdown/astro.config.mjs +31 -0
- package/dist/examples-apps/event-countdown/package.json +51 -0
- package/dist/examples-apps/event-countdown/src/components/countdown-preview.tsx +164 -0
- package/dist/examples-apps/event-countdown/src/components/countdown-timer-settings.tsx +199 -0
- package/dist/examples-apps/event-countdown/src/dashboard/pages/countdown-timer-settings/extensions.ts +7 -0
- package/dist/examples-apps/event-countdown/src/dashboard/pages/countdown-timer-settings/page.tsx +142 -0
- package/dist/examples-apps/event-countdown/src/dashboard/withProviders.tsx +22 -0
- package/dist/examples-apps/event-countdown/src/extensions.ts +12 -0
- package/dist/examples-apps/event-countdown/src/index.ts +2 -0
- package/dist/examples-apps/event-countdown/src/site/embedded-scripts/countdown-timer/embedded.html +328 -0
- package/dist/examples-apps/event-countdown/src/site/embedded-scripts/countdown-timer/extensions.ts +8 -0
- package/dist/examples-apps/event-countdown/src/types.ts +11 -0
- package/dist/examples-apps/event-countdown/tsconfig.json +9 -0
- package/dist/examples-apps/event-countdown/wix.config.json +4 -0
- package/dist/examples-apps/site-popup/package.json +43 -26
- package/dist/examples-apps/site-popup/src/components/activation-configuration.tsx +1 -1
- package/dist/examples-apps/site-popup/src/components/close-button.css +33 -0
- package/dist/examples-apps/site-popup/src/components/close-button.tsx +4 -3
- package/dist/examples-apps/site-popup/src/components/popup/index.css +133 -3
- package/dist/examples-apps/site-popup/src/components/popup/index.tsx +10 -10
- package/dist/examples-apps/site-popup/src/components/site-popup-settings.tsx +4 -4
- package/dist/examples-apps/site-popup/src/dashboard/pages/page.tsx +2 -2
- package/dist/examples-apps/site-popup/src/dashboard/withProviders.tsx +4 -1
- package/dist/examples-apps/site-popup/src/extensions.ts +21 -0
- package/dist/examples-apps/site-popup/src/site/embedded-scripts/site-popup/embedded.html +1 -0
- package/dist/examples-apps/site-popup/src/site/embedded-scripts/site-popup/popup-overlay/index.css +21 -3
- package/dist/examples-apps/site-popup/src/site/embedded-scripts/site-popup/popup-overlay/index.tsx +8 -9
- package/dist/examples-apps/site-popup/src/types.ts +1 -1
- package/dist/out.js +4716 -898
- package/dist/wix-cli-templates/src/dashboard/pages/page.tsx +0 -4
- package/dist/wix-cli-templates/src/site/embedded-scripts/my-script/embedded.html +1 -2
- package/package.json +2 -2
- package/dist/examples-apps/mixpanel-analytics/src/dashboard/pages/page.json +0 -5
- package/dist/examples-apps/mixpanel-analytics/src/site/embedded-scripts/mixpanel-analytics/embedded.json +0 -7
- package/dist/examples-apps/site-popup/package-lock.json +0 -8033
- package/dist/examples-apps/site-popup/postcss.config.js +0 -7
- package/dist/examples-apps/site-popup/src/env.d.ts +0 -4
- package/dist/examples-apps/site-popup/src/site/embedded-scripts/site-popup/embedded.json +0 -7
- package/dist/examples-apps/site-popup/src/site/embedded-scripts/site-popup/params.dev.json +0 -7
- package/dist/examples-apps/site-popup/tailwind.config.js +0 -8
- package/dist/wix-cli-templates/src/dashboard/pages/wix_logo.svg +0 -18
- package/dist/wix-cli-templates/src/site/embedded-scripts/my-script/embedded.json +0 -7
- package/dist/wix-cli-templates/src/site/embedded-scripts/my-script/logger.ts +0 -1
- package/dist/wix-cli-templates/src/site/embedded-scripts/my-script/params.dev.json +0 -3
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Wix Astro Blank Template
|
|
2
|
+
|
|
3
|
+
Our Astro templates are still in development and subject to change.
|
|
4
|
+
|
|
5
|
+
To use a template, follow the [Wix CLI for Headless Quick Start](https://dev.wix.com/docs/go-headless/develop-your-project/wix-managed-headless/get-started/quick-start), and select the desired template during the setup process.
|
|
6
|
+
|
|
7
|
+
## Need help?
|
|
8
|
+
|
|
9
|
+
For documentation and support, check out:
|
|
10
|
+
|
|
11
|
+
- [Wix Headless Documentation](https://dev.wix.com/docs/go-headless)
|
|
12
|
+
- [Wix SDK Documentation](https://dev.wix.com/docs/sdk)
|
|
13
|
+
- [Community on Discord](https://discord.gg/n6TBrSnYTp)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { defineConfig } from 'astro/config';
|
|
3
|
+
import wix from "@wix/astro";
|
|
4
|
+
|
|
5
|
+
import react from "@astrojs/react";
|
|
6
|
+
import cloudflare from "@astrojs/cloudflare";
|
|
7
|
+
|
|
8
|
+
// https://astro.build/config
|
|
9
|
+
export default defineConfig({
|
|
10
|
+
integrations: [wix(), react()],
|
|
11
|
+
|
|
12
|
+
adapter: cloudflare({
|
|
13
|
+
platformProxy: {
|
|
14
|
+
enabled: false,
|
|
15
|
+
},
|
|
16
|
+
}),
|
|
17
|
+
|
|
18
|
+
image: {
|
|
19
|
+
domains: ["static.wixstatic.com"],
|
|
20
|
+
},
|
|
21
|
+
security: {
|
|
22
|
+
checkOrigin: false
|
|
23
|
+
},
|
|
24
|
+
vite: {
|
|
25
|
+
server: {
|
|
26
|
+
allowedHosts: ['.wix-code.com']
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
devToolbar: { enabled: false },
|
|
30
|
+
output: "server",
|
|
31
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "my-custom-app",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"scripts": {
|
|
5
|
+
"astro": "astro",
|
|
6
|
+
"dev": "wix dev",
|
|
7
|
+
"build": "wix build",
|
|
8
|
+
"wix": "wix",
|
|
9
|
+
"preview": "wix preview",
|
|
10
|
+
"release": "wix release",
|
|
11
|
+
"generate": "wix generate",
|
|
12
|
+
"env": "wix env"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@astrojs/cloudflare": "^12.5.3",
|
|
16
|
+
"@astrojs/react": "^4.3.0",
|
|
17
|
+
"@tanstack/react-query": "^5.90.5",
|
|
18
|
+
"@types/react": "^18.3.1",
|
|
19
|
+
"@types/react-dom": "^18.3.1",
|
|
20
|
+
"@wix/app-management": "^1.0.122",
|
|
21
|
+
"@wix/astro": "^2.8.0",
|
|
22
|
+
"@wix/auto-patterns": "^1.40.0",
|
|
23
|
+
"@wix/cli": "^1.1.92",
|
|
24
|
+
"@wix/crm": "^1.0.1071",
|
|
25
|
+
"@wix/dashboard": "^1.3.40",
|
|
26
|
+
"@wix/data": "^1.0.290",
|
|
27
|
+
"@wix/design-system": "^1.217.0",
|
|
28
|
+
"@wix/ecom": "^1.0.1354",
|
|
29
|
+
"@wix/essentials": "^0.1.23",
|
|
30
|
+
"@wix/patterns": "^1.290.0",
|
|
31
|
+
"@wix/sdk": "^1.15.23",
|
|
32
|
+
"@wix/sdk-types": "^1.0.0",
|
|
33
|
+
"@wix/site-site": "^1.26.0",
|
|
34
|
+
"@wix/stores": "^1.0.533",
|
|
35
|
+
"@wix/wix-ui-icons-common": "^3.90.0",
|
|
36
|
+
"astro": "^5.8.0",
|
|
37
|
+
"react": "18.3.1",
|
|
38
|
+
"react-dom": "18.3.1",
|
|
39
|
+
"react-router-dom": "^6.0.0",
|
|
40
|
+
"typescript": "^5.8.3"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@astrojs/cloudflare": "^12.5.3",
|
|
44
|
+
"@astrojs/react": "^4.3.0",
|
|
45
|
+
"@types/react": "^18.3.1",
|
|
46
|
+
"@types/react-dom": "^18.3.1",
|
|
47
|
+
"@wix/cli": "^1.1.92",
|
|
48
|
+
"react": "18.3.1",
|
|
49
|
+
"react-dom": "18.3.1"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { useState, useEffect, type FC } from 'react';
|
|
2
|
+
import { Card } from '@wix/design-system';
|
|
3
|
+
import type { CountdownTimerOptions } from '../types';
|
|
4
|
+
|
|
5
|
+
interface TimeLeft {
|
|
6
|
+
days: number;
|
|
7
|
+
hours: number;
|
|
8
|
+
minutes: number;
|
|
9
|
+
seconds: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface Props extends CountdownTimerOptions {
|
|
13
|
+
className?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const CountdownPreview: FC<Props> = ({
|
|
17
|
+
eventTitle,
|
|
18
|
+
eventDescription,
|
|
19
|
+
targetDateTime,
|
|
20
|
+
completionMessage,
|
|
21
|
+
backgroundColor,
|
|
22
|
+
textColor,
|
|
23
|
+
position,
|
|
24
|
+
autoHide,
|
|
25
|
+
timerSize,
|
|
26
|
+
}) => {
|
|
27
|
+
const [timeLeft, setTimeLeft] = useState<TimeLeft>({
|
|
28
|
+
days: 0,
|
|
29
|
+
hours: 0,
|
|
30
|
+
minutes: 0,
|
|
31
|
+
seconds: 0,
|
|
32
|
+
});
|
|
33
|
+
const [isComplete, setIsComplete] = useState(false);
|
|
34
|
+
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
const calculateTimeLeft = () => {
|
|
37
|
+
const difference = +new Date(targetDateTime) - +new Date();
|
|
38
|
+
|
|
39
|
+
if (difference > 0) {
|
|
40
|
+
setTimeLeft({
|
|
41
|
+
days: Math.floor(difference / (1000 * 60 * 60 * 24)),
|
|
42
|
+
hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
|
|
43
|
+
minutes: Math.floor((difference / 1000 / 60) % 60),
|
|
44
|
+
seconds: Math.floor((difference / 1000) % 60),
|
|
45
|
+
});
|
|
46
|
+
setIsComplete(false);
|
|
47
|
+
} else {
|
|
48
|
+
setTimeLeft({ days: 0, hours: 0, minutes: 0, seconds: 0 });
|
|
49
|
+
setIsComplete(true);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
calculateTimeLeft();
|
|
54
|
+
const timer = setInterval(calculateTimeLeft, 1000);
|
|
55
|
+
|
|
56
|
+
return () => clearInterval(timer);
|
|
57
|
+
}, [targetDateTime]);
|
|
58
|
+
|
|
59
|
+
const getSizeStyles = () => {
|
|
60
|
+
switch (timerSize) {
|
|
61
|
+
case 'small':
|
|
62
|
+
return { fontSize: '14px', padding: '12px' };
|
|
63
|
+
case 'large':
|
|
64
|
+
return { fontSize: '24px', padding: '24px' };
|
|
65
|
+
default:
|
|
66
|
+
return { fontSize: '18px', padding: '18px' };
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
if (isComplete && autoHide) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const sizeStyles = getSizeStyles();
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<Card>
|
|
78
|
+
<Card.Header title="Preview" subtitle="How your countdown timer will appear on the site" />
|
|
79
|
+
<Card.Divider />
|
|
80
|
+
<Card.Content>
|
|
81
|
+
<div
|
|
82
|
+
style={{
|
|
83
|
+
position: 'relative',
|
|
84
|
+
minHeight: '400px',
|
|
85
|
+
backgroundColor: '#e8e8e8',
|
|
86
|
+
borderRadius: '8px',
|
|
87
|
+
padding: '20px',
|
|
88
|
+
display: 'flex',
|
|
89
|
+
alignItems: position.includes('top') ? 'flex-start' : position.includes('bottom') ? 'flex-end' : 'center',
|
|
90
|
+
justifyContent: position.includes('left') ? 'flex-start' : position.includes('right') ? 'flex-end' : 'center',
|
|
91
|
+
}}
|
|
92
|
+
>
|
|
93
|
+
<div
|
|
94
|
+
style={{
|
|
95
|
+
backgroundColor,
|
|
96
|
+
color: textColor,
|
|
97
|
+
padding: sizeStyles.padding,
|
|
98
|
+
borderRadius: '8px',
|
|
99
|
+
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
|
|
100
|
+
display: 'inline-flex',
|
|
101
|
+
flexDirection: 'column',
|
|
102
|
+
gap: '12px',
|
|
103
|
+
alignItems: 'center',
|
|
104
|
+
}}
|
|
105
|
+
>
|
|
106
|
+
<h3 style={{ color: textColor, margin: 0, fontSize: sizeStyles.fontSize, fontWeight: 'bold' }}>
|
|
107
|
+
{eventTitle}
|
|
108
|
+
</h3>
|
|
109
|
+
|
|
110
|
+
{eventDescription && (
|
|
111
|
+
<p style={{ color: textColor, textAlign: 'center', margin: 0, fontSize: '14px' }}>
|
|
112
|
+
{eventDescription}
|
|
113
|
+
</p>
|
|
114
|
+
)}
|
|
115
|
+
|
|
116
|
+
{isComplete ? (
|
|
117
|
+
<div style={{ color: textColor, fontWeight: 'bold', fontSize: sizeStyles.fontSize }}>
|
|
118
|
+
{completionMessage}
|
|
119
|
+
</div>
|
|
120
|
+
) : (
|
|
121
|
+
<div style={{ display: 'flex', gap: '6px', alignItems: 'center' }}>
|
|
122
|
+
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '4px' }}>
|
|
123
|
+
<div style={{ color: textColor, fontWeight: 'bold', fontSize: sizeStyles.fontSize }}>
|
|
124
|
+
{timeLeft.days.toString().padStart(2, '0')}
|
|
125
|
+
</div>
|
|
126
|
+
<div style={{ color: textColor, fontSize: '12px' }}>
|
|
127
|
+
Days
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
<div style={{ color: textColor, fontSize: sizeStyles.fontSize, fontWeight: 'bold' }}>:</div>
|
|
131
|
+
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '4px' }}>
|
|
132
|
+
<div style={{ color: textColor, fontWeight: 'bold', fontSize: sizeStyles.fontSize }}>
|
|
133
|
+
{timeLeft.hours.toString().padStart(2, '0')}
|
|
134
|
+
</div>
|
|
135
|
+
<div style={{ color: textColor, fontSize: '12px' }}>
|
|
136
|
+
Hours
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
<div style={{ color: textColor, fontSize: sizeStyles.fontSize, fontWeight: 'bold' }}>:</div>
|
|
140
|
+
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '4px' }}>
|
|
141
|
+
<div style={{ color: textColor, fontWeight: 'bold', fontSize: sizeStyles.fontSize }}>
|
|
142
|
+
{timeLeft.minutes.toString().padStart(2, '0')}
|
|
143
|
+
</div>
|
|
144
|
+
<div style={{ color: textColor, fontSize: '12px' }}>
|
|
145
|
+
Minutes
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
<div style={{ color: textColor, fontSize: sizeStyles.fontSize, fontWeight: 'bold' }}>:</div>
|
|
149
|
+
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '4px' }}>
|
|
150
|
+
<div style={{ color: textColor, fontWeight: 'bold', fontSize: sizeStyles.fontSize }}>
|
|
151
|
+
{timeLeft.seconds.toString().padStart(2, '0')}
|
|
152
|
+
</div>
|
|
153
|
+
<div style={{ color: textColor, fontSize: '12px' }}>
|
|
154
|
+
Seconds
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
)}
|
|
159
|
+
</div>
|
|
160
|
+
</div>
|
|
161
|
+
</Card.Content>
|
|
162
|
+
</Card>
|
|
163
|
+
);
|
|
164
|
+
};
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import React, { type FC } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Input,
|
|
4
|
+
InputArea,
|
|
5
|
+
Card,
|
|
6
|
+
FormField,
|
|
7
|
+
ColorInput,
|
|
8
|
+
Dropdown,
|
|
9
|
+
Checkbox,
|
|
10
|
+
Box,
|
|
11
|
+
type FormFieldProps,
|
|
12
|
+
} from '@wix/design-system';
|
|
13
|
+
import type { CountdownTimerOptions } from '../types';
|
|
14
|
+
|
|
15
|
+
interface Props {
|
|
16
|
+
options: CountdownTimerOptions;
|
|
17
|
+
onChange: (options: CountdownTimerOptions) => void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const CountdownTimerSettings: FC<Props> = ({ options, onChange }) => {
|
|
21
|
+
const getFieldStatus = (
|
|
22
|
+
field: keyof CountdownTimerOptions,
|
|
23
|
+
required: boolean = false
|
|
24
|
+
): Partial<FormFieldProps> => {
|
|
25
|
+
return required && !options[field]
|
|
26
|
+
? {
|
|
27
|
+
status: 'error',
|
|
28
|
+
statusMessage: 'Required.',
|
|
29
|
+
}
|
|
30
|
+
: {};
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const positionOptions = [
|
|
34
|
+
{ id: 'top-left', value: 'Top Left' },
|
|
35
|
+
{ id: 'top-right', value: 'Top Right' },
|
|
36
|
+
{ id: 'bottom-left', value: 'Bottom Left' },
|
|
37
|
+
{ id: 'bottom-right', value: 'Bottom Right' },
|
|
38
|
+
{ id: 'center', value: 'Center' },
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
const sizeOptions = [
|
|
42
|
+
{ id: 'small', value: 'Small' },
|
|
43
|
+
{ id: 'medium', value: 'Medium' },
|
|
44
|
+
{ id: 'large', value: 'Large' },
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<Box direction="vertical" gap="24px">
|
|
49
|
+
<Card>
|
|
50
|
+
<Card.Header
|
|
51
|
+
title="Event Details"
|
|
52
|
+
subtitle="Configure the basic information for your countdown event"
|
|
53
|
+
/>
|
|
54
|
+
<Card.Divider />
|
|
55
|
+
<Card.Content>
|
|
56
|
+
<Box gap="18px" direction="vertical">
|
|
57
|
+
<FormField
|
|
58
|
+
label="Event Title"
|
|
59
|
+
required
|
|
60
|
+
{...getFieldStatus('eventTitle', true)}
|
|
61
|
+
>
|
|
62
|
+
<Input
|
|
63
|
+
placeholder="Upcoming Event"
|
|
64
|
+
value={options.eventTitle}
|
|
65
|
+
onChange={(e) =>
|
|
66
|
+
onChange({
|
|
67
|
+
...options,
|
|
68
|
+
eventTitle: e.currentTarget.value,
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
/>
|
|
72
|
+
</FormField>
|
|
73
|
+
|
|
74
|
+
<FormField label="Event Description">
|
|
75
|
+
<InputArea
|
|
76
|
+
placeholder="Additional details about the event"
|
|
77
|
+
value={options.eventDescription || ''}
|
|
78
|
+
onChange={(e) =>
|
|
79
|
+
onChange({
|
|
80
|
+
...options,
|
|
81
|
+
eventDescription: e.currentTarget.value,
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
rows={3}
|
|
85
|
+
/>
|
|
86
|
+
</FormField>
|
|
87
|
+
|
|
88
|
+
<FormField
|
|
89
|
+
label="Target Date and Time"
|
|
90
|
+
required
|
|
91
|
+
{...getFieldStatus('targetDateTime', true)}
|
|
92
|
+
>
|
|
93
|
+
<Input
|
|
94
|
+
type="datetime-local"
|
|
95
|
+
value={options.targetDateTime}
|
|
96
|
+
onChange={(e) =>
|
|
97
|
+
onChange({
|
|
98
|
+
...options,
|
|
99
|
+
targetDateTime: e.currentTarget.value,
|
|
100
|
+
})
|
|
101
|
+
}
|
|
102
|
+
/>
|
|
103
|
+
</FormField>
|
|
104
|
+
|
|
105
|
+
<FormField label="Completion Message">
|
|
106
|
+
<Input
|
|
107
|
+
placeholder="Event has started!"
|
|
108
|
+
value={options.completionMessage}
|
|
109
|
+
onChange={(e) =>
|
|
110
|
+
onChange({
|
|
111
|
+
...options,
|
|
112
|
+
completionMessage: e.currentTarget.value,
|
|
113
|
+
})
|
|
114
|
+
}
|
|
115
|
+
/>
|
|
116
|
+
</FormField>
|
|
117
|
+
</Box>
|
|
118
|
+
</Card.Content>
|
|
119
|
+
</Card>
|
|
120
|
+
|
|
121
|
+
<Card>
|
|
122
|
+
<Card.Header
|
|
123
|
+
title="Visual Customization"
|
|
124
|
+
subtitle="Customize the appearance and behavior of your countdown timer"
|
|
125
|
+
/>
|
|
126
|
+
<Card.Divider />
|
|
127
|
+
<Card.Content>
|
|
128
|
+
<Box gap="18px" direction="vertical">
|
|
129
|
+
<FormField label="Background Color">
|
|
130
|
+
<ColorInput
|
|
131
|
+
value={options.backgroundColor}
|
|
132
|
+
onChange={(color) =>
|
|
133
|
+
onChange({
|
|
134
|
+
...options,
|
|
135
|
+
backgroundColor: color,
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
/>
|
|
139
|
+
</FormField>
|
|
140
|
+
|
|
141
|
+
<FormField label="Text Color">
|
|
142
|
+
<ColorInput
|
|
143
|
+
value={options.textColor}
|
|
144
|
+
onChange={(color) =>
|
|
145
|
+
onChange({
|
|
146
|
+
...options,
|
|
147
|
+
textColor: color,
|
|
148
|
+
})
|
|
149
|
+
}
|
|
150
|
+
/>
|
|
151
|
+
</FormField>
|
|
152
|
+
|
|
153
|
+
<FormField label="Display Position">
|
|
154
|
+
<Dropdown
|
|
155
|
+
placeholder="Select position"
|
|
156
|
+
options={positionOptions}
|
|
157
|
+
selectedId={options.position}
|
|
158
|
+
onSelect={(option) =>
|
|
159
|
+
onChange({
|
|
160
|
+
...options,
|
|
161
|
+
position: option.id as CountdownTimerOptions['position'],
|
|
162
|
+
})
|
|
163
|
+
}
|
|
164
|
+
/>
|
|
165
|
+
</FormField>
|
|
166
|
+
|
|
167
|
+
<FormField label="Timer Size">
|
|
168
|
+
<Dropdown
|
|
169
|
+
placeholder="Select size"
|
|
170
|
+
options={sizeOptions}
|
|
171
|
+
selectedId={options.timerSize}
|
|
172
|
+
onSelect={(option) =>
|
|
173
|
+
onChange({
|
|
174
|
+
...options,
|
|
175
|
+
timerSize: option.id as CountdownTimerOptions['timerSize'],
|
|
176
|
+
})
|
|
177
|
+
}
|
|
178
|
+
/>
|
|
179
|
+
</FormField>
|
|
180
|
+
|
|
181
|
+
<FormField label="Auto Hide When Complete">
|
|
182
|
+
<Checkbox
|
|
183
|
+
checked={options.autoHide}
|
|
184
|
+
onChange={(e) =>
|
|
185
|
+
onChange({
|
|
186
|
+
...options,
|
|
187
|
+
autoHide: e.target.checked,
|
|
188
|
+
})
|
|
189
|
+
}
|
|
190
|
+
>
|
|
191
|
+
Automatically hide the countdown timer when it reaches zero
|
|
192
|
+
</Checkbox>
|
|
193
|
+
</FormField>
|
|
194
|
+
</Box>
|
|
195
|
+
</Card.Content>
|
|
196
|
+
</Card>
|
|
197
|
+
</Box>
|
|
198
|
+
);
|
|
199
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as extensions from '@wix/astro/builders';
|
|
2
|
+
export const dashboardpagecountdownTimerSettings = extensions.backofficePage({
|
|
3
|
+
"id": "55494b14-6385-41a3-af6b-c165b0961f5f",
|
|
4
|
+
"title": "Countdown Timer Settings",
|
|
5
|
+
"routePath": "countdown-timer-settings",
|
|
6
|
+
"component": "./dashboard/pages/countdown-timer-settings/page.tsx"
|
|
7
|
+
})
|
package/dist/examples-apps/event-countdown/src/dashboard/pages/countdown-timer-settings/page.tsx
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { useEffect, useState, type FC } from 'react';
|
|
2
|
+
import { dashboard } from '@wix/dashboard';
|
|
3
|
+
import { embeddedScripts } from '@wix/app-management';
|
|
4
|
+
import {
|
|
5
|
+
Button,
|
|
6
|
+
Page,
|
|
7
|
+
Layout,
|
|
8
|
+
Cell,
|
|
9
|
+
Loader,
|
|
10
|
+
Box,
|
|
11
|
+
} from '@wix/design-system';
|
|
12
|
+
import '@wix/design-system/styles.global.css';
|
|
13
|
+
import withProviders from '../../withProviders';
|
|
14
|
+
import { CountdownTimerSettings } from '../../../components/countdown-timer-settings';
|
|
15
|
+
import { CountdownPreview } from '../../../components/countdown-preview';
|
|
16
|
+
import type { CountdownTimerOptions } from '../../../types';
|
|
17
|
+
|
|
18
|
+
const countdownTimerDefaultOptions: CountdownTimerOptions = {
|
|
19
|
+
eventTitle: 'Upcoming Event',
|
|
20
|
+
eventDescription: '',
|
|
21
|
+
targetDateTime: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 16), // 7 days from now
|
|
22
|
+
completionMessage: 'Event has started!',
|
|
23
|
+
backgroundColor: '#FFFFFF',
|
|
24
|
+
textColor: '#000000',
|
|
25
|
+
position: 'bottom-right',
|
|
26
|
+
autoHide: true,
|
|
27
|
+
timerSize: 'medium',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const CountdownTimerPage: FC = () => {
|
|
31
|
+
const [options, setOptions] = useState<CountdownTimerOptions>(countdownTimerDefaultOptions);
|
|
32
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
33
|
+
const [isSaving, setIsSaving] = useState(false);
|
|
34
|
+
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
const loadSettings = async () => {
|
|
37
|
+
try {
|
|
38
|
+
const embeddedScript = await embeddedScripts.getEmbeddedScript();
|
|
39
|
+
const data = embeddedScript.parameters as Partial<Record<keyof CountdownTimerOptions, string>> || {};
|
|
40
|
+
|
|
41
|
+
setOptions((prev) => ({
|
|
42
|
+
...prev,
|
|
43
|
+
eventTitle: data?.eventTitle || prev.eventTitle,
|
|
44
|
+
eventDescription: data?.eventDescription || prev.eventDescription || '',
|
|
45
|
+
targetDateTime: data?.targetDateTime || prev.targetDateTime,
|
|
46
|
+
completionMessage: data?.completionMessage || prev.completionMessage,
|
|
47
|
+
backgroundColor: data?.backgroundColor || prev.backgroundColor,
|
|
48
|
+
textColor: data?.textColor || prev.textColor,
|
|
49
|
+
position: (data?.position as CountdownTimerOptions['position']) || prev.position,
|
|
50
|
+
autoHide: data?.autoHide === 'true' ? true : data?.autoHide === 'false' ? false : prev.autoHide,
|
|
51
|
+
timerSize: (data?.timerSize as CountdownTimerOptions['timerSize']) || prev.timerSize,
|
|
52
|
+
}));
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.error('Failed to load embedded script settings:', error);
|
|
55
|
+
} finally {
|
|
56
|
+
setIsLoading(false);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
loadSettings();
|
|
61
|
+
}, []);
|
|
62
|
+
|
|
63
|
+
const handleSave = async () => {
|
|
64
|
+
if (!options.eventTitle || !options.targetDateTime) {
|
|
65
|
+
dashboard.showToast({
|
|
66
|
+
message: 'Please fill in all required fields',
|
|
67
|
+
type: 'error',
|
|
68
|
+
});
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
setIsSaving(true);
|
|
73
|
+
try {
|
|
74
|
+
// Convert all values to strings for embedded script parameters
|
|
75
|
+
await embeddedScripts.embedScript({
|
|
76
|
+
parameters: {
|
|
77
|
+
eventTitle: options.eventTitle,
|
|
78
|
+
eventDescription: options.eventDescription || '',
|
|
79
|
+
targetDateTime: options.targetDateTime,
|
|
80
|
+
completionMessage: options.completionMessage,
|
|
81
|
+
backgroundColor: options.backgroundColor,
|
|
82
|
+
textColor: options.textColor,
|
|
83
|
+
position: options.position,
|
|
84
|
+
autoHide: String(options.autoHide),
|
|
85
|
+
timerSize: options.timerSize,
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
dashboard.showToast({
|
|
90
|
+
message: 'Countdown timer settings saved successfully!',
|
|
91
|
+
type: 'success',
|
|
92
|
+
});
|
|
93
|
+
} catch (error) {
|
|
94
|
+
console.error('Failed to save settings:', error);
|
|
95
|
+
dashboard.showToast({
|
|
96
|
+
message: 'Failed to save settings. Please try again.',
|
|
97
|
+
type: 'error',
|
|
98
|
+
});
|
|
99
|
+
} finally {
|
|
100
|
+
setIsSaving(false);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
<Page height="100vh">
|
|
106
|
+
<Page.Header
|
|
107
|
+
title="Countdown Timer Settings"
|
|
108
|
+
subtitle="Configure your countdown timer with event details and visual customization options"
|
|
109
|
+
actionsBar={
|
|
110
|
+
<Button
|
|
111
|
+
skin="inverted"
|
|
112
|
+
disabled={!options.eventTitle || !options.targetDateTime || isSaving}
|
|
113
|
+
onClick={handleSave}
|
|
114
|
+
>
|
|
115
|
+
{isSaving ? 'Saving...' : 'Save'}
|
|
116
|
+
</Button>
|
|
117
|
+
}
|
|
118
|
+
/>
|
|
119
|
+
<Page.Content>
|
|
120
|
+
{isLoading ? (
|
|
121
|
+
<Box align="center" verticalAlign="middle" height="50vh">
|
|
122
|
+
<Loader text="Loading countdown timer settings..." />
|
|
123
|
+
</Box>
|
|
124
|
+
) : (
|
|
125
|
+
<Layout gap="24px">
|
|
126
|
+
<Cell span={6}>
|
|
127
|
+
<CountdownTimerSettings
|
|
128
|
+
options={options}
|
|
129
|
+
onChange={setOptions}
|
|
130
|
+
/>
|
|
131
|
+
</Cell>
|
|
132
|
+
<Cell span={6}>
|
|
133
|
+
<CountdownPreview {...options} />
|
|
134
|
+
</Cell>
|
|
135
|
+
</Layout>
|
|
136
|
+
)}
|
|
137
|
+
</Page.Content>
|
|
138
|
+
</Page>
|
|
139
|
+
);
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
export default withProviders(CountdownTimerPage);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { QueryClientProvider, QueryClient } from '@tanstack/react-query';
|
|
3
|
+
import { WixDesignSystemProvider } from '@wix/design-system';
|
|
4
|
+
import { i18n } from '@wix/essentials';
|
|
5
|
+
|
|
6
|
+
const queryClient = new QueryClient();
|
|
7
|
+
|
|
8
|
+
export default function withProviders<P extends {} = {}>(Component: React.FC<P>) {
|
|
9
|
+
return function DashboardProviders(props: P) {
|
|
10
|
+
const locale = i18n.getLocale();
|
|
11
|
+
return (
|
|
12
|
+
<WixDesignSystemProvider locale={locale} features={{ newColorsBranding: true }}>
|
|
13
|
+
<QueryClientProvider client={queryClient}>
|
|
14
|
+
<Component {...props} />
|
|
15
|
+
</QueryClientProvider>
|
|
16
|
+
</WixDesignSystemProvider>
|
|
17
|
+
);
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Also export as named export for backwards compatibility
|
|
22
|
+
export { withProviders };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { app } from '@wix/astro/builders';
|
|
2
|
+
import * as allExtensions from './index';
|
|
3
|
+
|
|
4
|
+
// Get all exported extensions
|
|
5
|
+
const extensionList = Object.values(allExtensions);
|
|
6
|
+
|
|
7
|
+
const appBuilder = app();
|
|
8
|
+
extensionList.forEach(extension => {
|
|
9
|
+
appBuilder.use(extension);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export default appBuilder;
|