@wix/ditto-codegen-public 1.0.178 → 1.0.180

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.
@@ -0,0 +1,116 @@
1
+ import { items } from '@wix/data';
2
+ import type { SurveyQuestion, SurveyResponse, QuestionStats } from './types';
3
+
4
+ /**
5
+ * Creates a new survey question
6
+ */
7
+ export async function createQuestion(
8
+ questionData: Omit<SurveyQuestion, '_id' | '_createdDate' | '_updatedDate' | '_owner'>
9
+ ): Promise<SurveyQuestion> {
10
+ try {
11
+ const result = await items.insert('survey-questions', questionData);
12
+ return result as SurveyQuestion;
13
+ } catch (error) {
14
+ console.error('Error creating survey question:', error);
15
+ throw new Error(
16
+ error instanceof Error ? error.message : 'Failed to create survey question'
17
+ );
18
+ }
19
+ }
20
+
21
+ /**
22
+ * Retrieves all survey questions
23
+ */
24
+ export async function getAllQuestions(): Promise<items.WixDataResult<SurveyQuestion>> {
25
+ try {
26
+ const result = await items.query('survey-questions')
27
+ .descending('_createdDate')
28
+ .find();
29
+ return result as items.WixDataResult<SurveyQuestion>;
30
+ } catch (error) {
31
+ console.error('Error fetching survey questions:', error);
32
+ throw new Error(
33
+ error instanceof Error ? error.message : 'Failed to fetch survey questions'
34
+ );
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Updates an existing survey question
40
+ */
41
+ export async function updateQuestion(questionData: SurveyQuestion): Promise<SurveyQuestion> {
42
+ try {
43
+ if (!questionData._id) {
44
+ throw new Error('Question ID is required for update');
45
+ }
46
+ const result = await items.update('survey-questions', questionData);
47
+ return result as SurveyQuestion;
48
+ } catch (error) {
49
+ console.error('Error updating survey question:', error);
50
+ throw new Error(
51
+ error instanceof Error ? error.message : 'Failed to update survey question'
52
+ );
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Deletes a survey question by ID
58
+ */
59
+ export async function deleteQuestion(questionId: string): Promise<SurveyQuestion> {
60
+ try {
61
+ if (!questionId) {
62
+ throw new Error('Question ID is required for deletion');
63
+ }
64
+ const result = await items.remove('survey-questions', questionId);
65
+ return result as SurveyQuestion;
66
+ } catch (error) {
67
+ console.error('Error deleting survey question:', error);
68
+ throw new Error(
69
+ error instanceof Error ? error.message : 'Failed to delete survey question'
70
+ );
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Gets statistics for a specific question
76
+ */
77
+ export async function getQuestionStats(questionId: string): Promise<QuestionStats> {
78
+ try {
79
+ const responses = await items.query('survey-responses')
80
+ .eq('questionId', questionId)
81
+ .find();
82
+
83
+ const responseItems = responses.items as SurveyResponse[];
84
+ const totalResponses = responseItems.length;
85
+
86
+ if (totalResponses === 0) {
87
+ return {
88
+ totalResponses: 0,
89
+ averageRating: 0,
90
+ ratingDistribution: {}
91
+ };
92
+ }
93
+
94
+ const ratings = responseItems.map(r => r.rating);
95
+ const averageRating = ratings.reduce((sum, rating) => sum + rating, 0) / totalResponses;
96
+
97
+ const ratingDistribution: { [rating: number]: number } = {};
98
+ ratings.forEach(rating => {
99
+ ratingDistribution[rating] = (ratingDistribution[rating] || 0) + 1;
100
+ });
101
+
102
+ return {
103
+ totalResponses,
104
+ averageRating: Math.round(averageRating * 100) / 100,
105
+ ratingDistribution
106
+ };
107
+ } catch (error) {
108
+ console.error('Error fetching question stats:', error);
109
+ return {
110
+ totalResponses: 0,
111
+ averageRating: 0,
112
+ ratingDistribution: {}
113
+ };
114
+ }
115
+ }
116
+
@@ -0,0 +1,23 @@
1
+ import React, { type FC } from 'react';
2
+ import { Page, WixDesignSystemProvider, Box, Loader } from '@wix/design-system';
3
+
4
+ interface PageLoaderProps {
5
+ title: string;
6
+ message?: string;
7
+ }
8
+
9
+ export const PageLoader: FC<PageLoaderProps> = ({ title, message = 'Loading...' }) => {
10
+ return (
11
+ <WixDesignSystemProvider features={{ newColorsBranding: true }}>
12
+ <Page height="100vh">
13
+ <Page.Header title={title} />
14
+ <Page.Content>
15
+ <Box align="center" verticalAlign="middle" height="50vh">
16
+ <Loader text={message} />
17
+ </Box>
18
+ </Page.Content>
19
+ </Page>
20
+ </WixDesignSystemProvider>
21
+ );
22
+ };
23
+
@@ -0,0 +1,84 @@
1
+ import React, { type FC } from 'react';
2
+ import {
3
+ Modal,
4
+ CustomModalLayout,
5
+ FormField,
6
+ Input,
7
+ ToggleSwitch,
8
+ Layout,
9
+ Cell,
10
+ } from '@wix/design-system';
11
+ import type { SurveyQuestion, QuestionFormData } from '../types';
12
+
13
+ interface QuestionModalProps {
14
+ isOpen: boolean;
15
+ editingQuestion: SurveyQuestion | null;
16
+ formData: QuestionFormData;
17
+ onFormChange: (data: QuestionFormData) => void;
18
+ onSave: () => void;
19
+ onClose: () => void;
20
+ }
21
+
22
+ export const QuestionModal: FC<QuestionModalProps> = ({
23
+ isOpen,
24
+ editingQuestion,
25
+ formData,
26
+ onFormChange,
27
+ onSave,
28
+ onClose,
29
+ }) => {
30
+ return (
31
+ <Modal isOpen={isOpen} onRequestClose={onClose}>
32
+ <CustomModalLayout
33
+ primaryButtonText="Save"
34
+ secondaryButtonText="Cancel"
35
+ onCloseButtonClick={onClose}
36
+ primaryButtonOnClick={onSave}
37
+ secondaryButtonOnClick={onClose}
38
+ title={`${editingQuestion ? 'Edit' : 'Add'} Survey Question`}
39
+ content={
40
+ <Layout gap="24px">
41
+ <Cell span={12}>
42
+ <FormField label="Question Text" required>
43
+ <Input
44
+ value={formData.questionText}
45
+ onChange={(e) =>
46
+ onFormChange({ ...formData, questionText: e.target.value })
47
+ }
48
+ placeholder="How would you rate our service?"
49
+ />
50
+ </FormField>
51
+ </Cell>
52
+ <Cell span={6}>
53
+ <FormField label="Maximum Rating">
54
+ <Input
55
+ type="number"
56
+ value={formData.maxRating.toString()}
57
+ onChange={(e) =>
58
+ onFormChange({
59
+ ...formData,
60
+ maxRating: Math.max(1, Math.min(10, Number(e.target.value))),
61
+ })
62
+ }
63
+ min={1}
64
+ max={10}
65
+ />
66
+ </FormField>
67
+ </Cell>
68
+ <Cell span={6}>
69
+ <FormField label="Active" labelPlacement="right" stretchContent={false}>
70
+ <ToggleSwitch
71
+ checked={formData.isActive}
72
+ onChange={() =>
73
+ onFormChange({ ...formData, isActive: !formData.isActive })
74
+ }
75
+ />
76
+ </FormField>
77
+ </Cell>
78
+ </Layout>
79
+ }
80
+ />
81
+ </Modal>
82
+ );
83
+ };
84
+
@@ -0,0 +1,139 @@
1
+ import React, { type FC } from 'react';
2
+ import {
3
+ Table,
4
+ TableActionCell,
5
+ TableToolbar,
6
+ Badge,
7
+ Box,
8
+ Text,
9
+ } from '@wix/design-system';
10
+ import * as Icons from '@wix/wix-ui-icons-common';
11
+ import type { SurveyQuestion, QuestionStats } from '../types';
12
+
13
+ interface QuestionsTableProps {
14
+ questions: SurveyQuestion[];
15
+ questionStats: Record<string, QuestionStats>;
16
+ onEdit: (question: SurveyQuestion) => void;
17
+ onDelete: (questionId: string, questionText: string) => void;
18
+ onToggleStatus: (question: SurveyQuestion) => void;
19
+ }
20
+
21
+ export const QuestionsTable: FC<QuestionsTableProps> = ({
22
+ questions,
23
+ questionStats,
24
+ onEdit,
25
+ onDelete,
26
+ onToggleStatus,
27
+ }) => {
28
+ const columns = [
29
+ {
30
+ title: 'Question',
31
+ render: (question: SurveyQuestion) => (
32
+ <Box direction="vertical" gap="3px">
33
+ <Text size="medium" weight="normal">
34
+ {question.questionText}
35
+ </Text>
36
+ <Box gap="6px">
37
+ <Badge
38
+ skin={question.isActive ? 'success' : 'neutral'}
39
+ size="small"
40
+ >
41
+ {question.isActive ? 'Active' : 'Inactive'}
42
+ </Badge>
43
+ <Text size="tiny" secondary>
44
+ Max Rating: {question.maxRating}
45
+ </Text>
46
+ </Box>
47
+ </Box>
48
+ ),
49
+ width: 'auto',
50
+ },
51
+ {
52
+ title: 'Responses',
53
+ render: (question: SurveyQuestion) => {
54
+ const stats = question._id ? questionStats[question._id] : null;
55
+ return (
56
+ <Box direction="vertical" gap="3px">
57
+ <Text size="medium" weight="bold">
58
+ {stats?.totalResponses || 0}
59
+ </Text>
60
+ <Text size="tiny" secondary>
61
+ Total responses
62
+ </Text>
63
+ </Box>
64
+ );
65
+ },
66
+ width: '120px',
67
+ },
68
+ {
69
+ title: 'Average Rating',
70
+ render: (question: SurveyQuestion) => {
71
+ const stats = question._id ? questionStats[question._id] : null;
72
+ return (
73
+ <Box direction="vertical" gap="3px">
74
+ <Text size="medium" weight="bold">
75
+ {stats?.averageRating || 0}
76
+ </Text>
77
+ <Text size="tiny" secondary>
78
+ out of {question.maxRating}
79
+ </Text>
80
+ </Box>
81
+ );
82
+ },
83
+ width: '120px',
84
+ },
85
+ {
86
+ title: 'Created',
87
+ render: (question: SurveyQuestion) => (
88
+ <Text size="small">
89
+ {question._createdDate
90
+ ? new Date(question._createdDate).toLocaleDateString()
91
+ : ''}
92
+ </Text>
93
+ ),
94
+ width: '100px',
95
+ },
96
+ {
97
+ title: 'Actions',
98
+ render: (question: SurveyQuestion) => (
99
+ <TableActionCell
100
+ primaryAction={{
101
+ text: 'Edit',
102
+ onClick: () => onEdit(question),
103
+ }}
104
+ secondaryActions={[
105
+ {
106
+ text: question.isActive ? 'Deactivate' : 'Activate',
107
+ icon: question.isActive ? <Icons.Hidden /> : <Icons.Visible />,
108
+ onClick: () => onToggleStatus(question),
109
+ },
110
+ {
111
+ text: 'Delete',
112
+ icon: <Icons.Delete />,
113
+ onClick: () => {
114
+ if (question._id) {
115
+ onDelete(question._id, question.questionText);
116
+ }
117
+ },
118
+ },
119
+ ]}
120
+ />
121
+ ),
122
+ width: '120px',
123
+ },
124
+ ];
125
+
126
+ return (
127
+ <Table data={questions} columns={columns}>
128
+ <TableToolbar>
129
+ <TableToolbar.ItemGroup position="start">
130
+ <TableToolbar.Item>
131
+ <TableToolbar.Title>Survey Questions</TableToolbar.Title>
132
+ </TableToolbar.Item>
133
+ </TableToolbar.ItemGroup>
134
+ </TableToolbar>
135
+ <Table.Content />
136
+ </Table>
137
+ );
138
+ };
139
+
@@ -0,0 +1,99 @@
1
+ import React, { type FC } from 'react';
2
+ import {
3
+ Button,
4
+ Page,
5
+ WixDesignSystemProvider,
6
+ EmptyState,
7
+ } from '@wix/design-system';
8
+ import * as Icons from '@wix/wix-ui-icons-common';
9
+
10
+ import type { SurveyQuestion, QuestionStats, QuestionFormData } from '../types';
11
+ import { SurveyStats } from './SurveyStats';
12
+ import { QuestionModal } from './QuestionModal';
13
+ import { QuestionsTable } from './QuestionsTable';
14
+
15
+ interface SurveyPageLayoutProps {
16
+ questions: SurveyQuestion[];
17
+ questionStats: Record<string, QuestionStats>;
18
+ activeQuestions: number;
19
+ totalResponses: number;
20
+ isModalOpen: boolean;
21
+ editingQuestion: SurveyQuestion | null;
22
+ formData: QuestionFormData;
23
+ onOpenModal: (question?: SurveyQuestion) => void;
24
+ onCloseModal: () => void;
25
+ onFormChange: (data: QuestionFormData) => void;
26
+ onSave: () => void;
27
+ onDelete: (questionId: string, questionText: string) => void;
28
+ onToggleStatus: (question: SurveyQuestion) => void;
29
+ }
30
+
31
+ export const SurveyPageLayout: FC<SurveyPageLayoutProps> = ({
32
+ questions,
33
+ questionStats,
34
+ activeQuestions,
35
+ totalResponses,
36
+ isModalOpen,
37
+ editingQuestion,
38
+ formData,
39
+ onOpenModal,
40
+ onCloseModal,
41
+ onFormChange,
42
+ onSave,
43
+ onDelete,
44
+ onToggleStatus,
45
+ }) => {
46
+ return (
47
+ <WixDesignSystemProvider features={{ newColorsBranding: true }}>
48
+ <Page height="100vh">
49
+ <Page.Header
50
+ title="Survey Manager"
51
+ subtitle="Create and manage rating survey questions, view aggregated results"
52
+ actionsBar={
53
+ <Button onClick={() => onOpenModal()} prefixIcon={<Icons.Add />}>
54
+ Add Question
55
+ </Button>
56
+ }
57
+ />
58
+ <Page.Content>
59
+ {questions.length === 0 ? (
60
+ <EmptyState
61
+ title="No survey questions yet"
62
+ subtitle="Create your first rating question to start collecting feedback from visitors"
63
+ skin="page"
64
+ >
65
+ <Button onClick={() => onOpenModal()} prefixIcon={<Icons.Add />}>
66
+ Create First Question
67
+ </Button>
68
+ </EmptyState>
69
+ ) : (
70
+ <>
71
+ <SurveyStats
72
+ totalQuestions={questions.length}
73
+ activeQuestions={activeQuestions}
74
+ totalResponses={totalResponses}
75
+ />
76
+ <QuestionsTable
77
+ questions={questions}
78
+ questionStats={questionStats}
79
+ onEdit={onOpenModal}
80
+ onDelete={onDelete}
81
+ onToggleStatus={onToggleStatus}
82
+ />
83
+ </>
84
+ )}
85
+ </Page.Content>
86
+ </Page>
87
+
88
+ <QuestionModal
89
+ isOpen={isModalOpen}
90
+ editingQuestion={editingQuestion}
91
+ formData={formData}
92
+ onFormChange={onFormChange}
93
+ onSave={onSave}
94
+ onClose={onCloseModal}
95
+ />
96
+ </WixDesignSystemProvider>
97
+ );
98
+ };
99
+
@@ -0,0 +1,50 @@
1
+ import React, { type FC } from 'react';
2
+ import { Box, Card, Heading, Text } from '@wix/design-system';
3
+
4
+ interface SurveyStatsProps {
5
+ totalQuestions: number;
6
+ activeQuestions: number;
7
+ totalResponses: number;
8
+ }
9
+
10
+ export const SurveyStats: FC<SurveyStatsProps> = ({
11
+ totalQuestions,
12
+ activeQuestions,
13
+ totalResponses,
14
+ }) => {
15
+ return (
16
+ <Box gap="24px" marginBottom="24px">
17
+ <Card>
18
+ <Card.Content>
19
+ <Box direction="vertical" gap="6px">
20
+ <Heading size="small">Total Questions</Heading>
21
+ <Text size="medium" weight="bold">
22
+ {totalQuestions}
23
+ </Text>
24
+ </Box>
25
+ </Card.Content>
26
+ </Card>
27
+ <Card>
28
+ <Card.Content>
29
+ <Box direction="vertical" gap="6px">
30
+ <Heading size="small">Active Questions</Heading>
31
+ <Text size="medium" weight="bold">
32
+ {activeQuestions}
33
+ </Text>
34
+ </Box>
35
+ </Card.Content>
36
+ </Card>
37
+ <Card>
38
+ <Card.Content>
39
+ <Box direction="vertical" gap="6px">
40
+ <Heading size="small">Total Responses</Heading>
41
+ <Text size="medium" weight="bold">
42
+ {totalResponses}
43
+ </Text>
44
+ </Box>
45
+ </Card.Content>
46
+ </Card>
47
+ </Box>
48
+ );
49
+ };
50
+
@@ -1,184 +1,39 @@
1
1
  import React, { useState, useEffect, type FC } from 'react';
2
2
  import { dashboard } from '@wix/dashboard';
3
- import { items } from '@wix/data';
4
- import {
5
- Button,
6
- Page,
7
- WixDesignSystemProvider,
8
- Table,
9
- TableActionCell,
10
- TableToolbar,
11
- Modal,
12
- CustomModalLayout,
13
- FormField,
14
- Input,
15
- ToggleSwitch,
16
- Layout,
17
- Cell,
18
- Badge,
19
- Box,
20
- Text,
21
- EmptyState,
22
- Loader,
23
- Card,
24
- Heading,
25
- } from '@wix/design-system';
26
3
  import '@wix/design-system/styles.global.css';
27
- import * as Icons from '@wix/wix-ui-icons-common';
28
-
29
- export type WixDataItem = items.WixDataItem;
30
-
31
- // Type definitions based on the CMS collections
32
- interface SurveyQuestion extends WixDataItem {
33
- questionText: string;
34
- maxRating: number;
35
- isActive: boolean;
36
- }
37
-
38
- interface SurveyResponse extends WixDataItem {
39
- questionId: string;
40
- rating: number;
41
- submittedAt: Date;
42
- }
43
-
44
- interface QuestionStats {
45
- totalResponses: number;
46
- averageRating: number;
47
- ratingDistribution: { [rating: number]: number };
48
- }
49
-
50
- /**
51
- * Creates a new survey question
52
- */
53
- async function createQuestion(questionData: Omit<SurveyQuestion, '_id' | '_createdDate' | '_updatedDate' | '_owner'>): Promise<SurveyQuestion> {
54
- try {
55
- const result = await items.insert('survey-questions', questionData);
56
- return result as SurveyQuestion;
57
- } catch (error) {
58
- console.error('Error creating survey question:', error);
59
- throw new Error(
60
- error instanceof Error ? error.message : 'Failed to create survey question'
61
- );
62
- }
63
- }
64
-
65
- /**
66
- * Retrieves all survey questions
67
- */
68
- async function getAllQuestions(): Promise<items.WixDataResult<SurveyQuestion>> {
69
- try {
70
- const result = await items.query('survey-questions')
71
- .descending('_createdDate')
72
- .find();
73
- return result as items.WixDataResult<SurveyQuestion>;
74
- } catch (error) {
75
- console.error('Error fetching survey questions:', error);
76
- throw new Error(
77
- error instanceof Error ? error.message : 'Failed to fetch survey questions'
78
- );
79
- }
80
- }
81
4
 
82
- /**
83
- * Updates an existing survey question
84
- */
85
- async function updateQuestion(questionData: SurveyQuestion): Promise<SurveyQuestion> {
86
- try {
87
- if (!questionData._id) {
88
- throw new Error('Question ID is required for update');
89
- }
90
- const result = await items.update('survey-questions', questionData);
91
- return result as SurveyQuestion;
92
- } catch (error) {
93
- console.error('Error updating survey question:', error);
94
- throw new Error(
95
- error instanceof Error ? error.message : 'Failed to update survey question'
96
- );
97
- }
98
- }
99
-
100
- /**
101
- * Deletes a survey question by ID
102
- */
103
- async function deleteQuestion(questionId: string): Promise<SurveyQuestion> {
104
- try {
105
- if (!questionId) {
106
- throw new Error('Question ID is required for deletion');
107
- }
108
- const result = await items.remove('survey-questions', questionId);
109
- return result as SurveyQuestion;
110
- } catch (error) {
111
- console.error('Error deleting survey question:', error);
112
- throw new Error(
113
- error instanceof Error ? error.message : 'Failed to delete survey question'
114
- );
115
- }
116
- }
117
-
118
- /**
119
- * Gets statistics for a specific question
120
- */
121
- async function getQuestionStats(questionId: string): Promise<QuestionStats> {
122
- try {
123
- const responses = await items.query('survey-responses')
124
- .eq('questionId', questionId)
125
- .find();
126
-
127
- const responseItems = responses.items as SurveyResponse[];
128
- const totalResponses = responseItems.length;
129
-
130
- if (totalResponses === 0) {
131
- return {
132
- totalResponses: 0,
133
- averageRating: 0,
134
- ratingDistribution: {}
135
- };
136
- }
137
-
138
- const ratings = responseItems.map(r => r.rating);
139
- const averageRating = ratings.reduce((sum, rating) => sum + rating, 0) / totalResponses;
140
-
141
- const ratingDistribution: { [rating: number]: number } = {};
142
- ratings.forEach(rating => {
143
- ratingDistribution[rating] = (ratingDistribution[rating] || 0) + 1;
144
- });
145
-
146
- return {
147
- totalResponses,
148
- averageRating: Math.round(averageRating * 100) / 100,
149
- ratingDistribution
150
- };
151
- } catch (error) {
152
- console.error('Error fetching question stats:', error);
153
- return {
154
- totalResponses: 0,
155
- averageRating: 0,
156
- ratingDistribution: {}
157
- };
158
- }
159
- }
5
+ import type { SurveyQuestion, QuestionStats, QuestionFormData } from './types';
6
+ import {
7
+ createQuestion,
8
+ getAllQuestions,
9
+ updateQuestion,
10
+ deleteQuestion,
11
+ getQuestionStats,
12
+ } from './apis';
13
+ import { PageLoader } from './components/PageLoader';
14
+ import { SurveyPageLayout } from './components/SurveyPageLayout';
15
+
16
+ const DEFAULT_FORM_DATA: QuestionFormData = {
17
+ questionText: '',
18
+ maxRating: 5,
19
+ isActive: true,
20
+ };
160
21
 
161
22
  const SurveyManager: FC = () => {
162
23
  const [questions, setQuestions] = useState<SurveyQuestion[]>([]);
163
- const [questionStats, setQuestionStats] = useState<{ [questionId: string]: QuestionStats }>({});
24
+ const [questionStats, setQuestionStats] = useState<Record<string, QuestionStats>>({});
164
25
  const [loading, setLoading] = useState(true);
165
26
  const [isModalOpen, setIsModalOpen] = useState(false);
166
27
  const [editingQuestion, setEditingQuestion] = useState<SurveyQuestion | null>(null);
167
- const [formData, setFormData] = useState({
168
- questionText: '',
169
- maxRating: 5,
170
- isActive: true
171
- });
28
+ const [formData, setFormData] = useState<QuestionFormData>(DEFAULT_FORM_DATA);
172
29
 
173
- // Load questions and their stats
174
30
  const loadQuestions = async () => {
175
31
  try {
176
32
  setLoading(true);
177
33
  const result = await getAllQuestions();
178
34
  setQuestions(result.items);
179
-
180
- // Load stats for each question
181
- const stats: { [questionId: string]: QuestionStats } = {};
35
+
36
+ const stats: Record<string, QuestionStats> = {};
182
37
  for (const question of result.items) {
183
38
  if (question._id) {
184
39
  stats[question._id] = await getQuestionStats(question._id);
@@ -188,7 +43,7 @@ const SurveyManager: FC = () => {
188
43
  } catch (error) {
189
44
  dashboard.showToast({
190
45
  message: 'Failed to load survey questions',
191
- type: 'error'
46
+ type: 'error',
192
47
  });
193
48
  } finally {
194
49
  setLoading(false);
@@ -201,76 +56,53 @@ const SurveyManager: FC = () => {
201
56
 
202
57
  const openModal = (question?: SurveyQuestion) => {
203
58
  setEditingQuestion(question || null);
204
-
205
- if (question) {
206
- setFormData({
207
- questionText: question.questionText,
208
- maxRating: question.maxRating,
209
- isActive: question.isActive
210
- });
211
- } else {
212
- setFormData({
213
- questionText: '',
214
- maxRating: 5,
215
- isActive: true
216
- });
217
- }
218
-
59
+ setFormData(
60
+ question
61
+ ? {
62
+ questionText: question.questionText,
63
+ maxRating: question.maxRating,
64
+ isActive: question.isActive,
65
+ }
66
+ : DEFAULT_FORM_DATA
67
+ );
219
68
  setIsModalOpen(true);
220
69
  };
221
70
 
222
71
  const closeModal = () => {
223
72
  setIsModalOpen(false);
224
73
  setEditingQuestion(null);
225
- setFormData({
226
- questionText: '',
227
- maxRating: 5,
228
- isActive: true
229
- });
74
+ setFormData(DEFAULT_FORM_DATA);
230
75
  };
231
76
 
232
77
  const handleSave = async () => {
233
- try {
234
- if (!formData.questionText.trim()) {
235
- dashboard.showToast({
236
- message: 'Question text is required',
237
- type: 'error'
238
- });
239
- return;
240
- }
78
+ if (!formData.questionText.trim()) {
79
+ dashboard.showToast({
80
+ message: 'Question text is required',
81
+ type: 'error',
82
+ });
83
+ return;
84
+ }
241
85
 
86
+ try {
242
87
  if (editingQuestion) {
243
- // Update existing question
244
- const updatedQuestion: SurveyQuestion = {
245
- ...editingQuestion,
246
- questionText: formData.questionText,
247
- maxRating: formData.maxRating,
248
- isActive: formData.isActive
249
- };
250
- await updateQuestion(updatedQuestion);
88
+ await updateQuestion({ ...editingQuestion, ...formData });
251
89
  dashboard.showToast({
252
90
  message: 'Question updated successfully',
253
- type: 'success'
91
+ type: 'success',
254
92
  });
255
93
  } else {
256
- // Create new question
257
- await createQuestion({
258
- questionText: formData.questionText,
259
- maxRating: formData.maxRating,
260
- isActive: formData.isActive
261
- });
94
+ await createQuestion(formData);
262
95
  dashboard.showToast({
263
96
  message: 'Question created successfully',
264
- type: 'success'
97
+ type: 'success',
265
98
  });
266
99
  }
267
-
268
100
  closeModal();
269
101
  loadQuestions();
270
102
  } catch (error) {
271
103
  dashboard.showToast({
272
104
  message: editingQuestion ? 'Failed to update question' : 'Failed to create question',
273
- type: 'error'
105
+ type: 'error',
274
106
  });
275
107
  }
276
108
  };
@@ -280,272 +112,60 @@ const SurveyManager: FC = () => {
280
112
  await deleteQuestion(questionId);
281
113
  dashboard.showToast({
282
114
  message: `"${questionText}" deleted successfully`,
283
- type: 'success'
115
+ type: 'success',
284
116
  });
285
117
  loadQuestions();
286
118
  } catch (error) {
287
119
  dashboard.showToast({
288
120
  message: 'Failed to delete question',
289
- type: 'error'
121
+ type: 'error',
290
122
  });
291
123
  }
292
124
  };
293
125
 
294
- const toggleQuestionStatus = async (question: SurveyQuestion) => {
126
+ const handleToggleStatus = async (question: SurveyQuestion) => {
295
127
  try {
296
- const updatedQuestion: SurveyQuestion = {
297
- ...question,
298
- isActive: !question.isActive
299
- };
300
- await updateQuestion(updatedQuestion);
128
+ await updateQuestion({ ...question, isActive: !question.isActive });
301
129
  dashboard.showToast({
302
- message: `Question ${updatedQuestion.isActive ? 'activated' : 'deactivated'}`,
303
- type: 'success'
130
+ message: `Question ${!question.isActive ? 'activated' : 'deactivated'}`,
131
+ type: 'success',
304
132
  });
305
133
  loadQuestions();
306
134
  } catch (error) {
307
135
  dashboard.showToast({
308
136
  message: 'Failed to update question status',
309
- type: 'error'
137
+ type: 'error',
310
138
  });
311
139
  }
312
140
  };
313
141
 
314
- const columns = [
315
- {
316
- title: 'Question',
317
- render: (question: SurveyQuestion) => (
318
- <Box direction="vertical" gap="3px">
319
- <Text size="medium" weight="normal">
320
- {question.questionText}
321
- </Text>
322
- <Box gap="6px">
323
- <Badge
324
- skin={question.isActive ? 'success' : 'neutral'}
325
- size="small"
326
- >
327
- {question.isActive ? 'Active' : 'Inactive'}
328
- </Badge>
329
- <Text size="tiny" secondary>
330
- Max Rating: {question.maxRating}
331
- </Text>
332
- </Box>
333
- </Box>
334
- ),
335
- width: 'auto'
336
- },
337
- {
338
- title: 'Responses',
339
- render: (question: SurveyQuestion) => {
340
- const stats = question._id ? questionStats[question._id] : null;
341
- return (
342
- <Box direction="vertical" gap="3px">
343
- <Text size="medium" weight="bold">
344
- {stats?.totalResponses || 0}
345
- </Text>
346
- <Text size="tiny" secondary>
347
- Total responses
348
- </Text>
349
- </Box>
350
- );
351
- },
352
- width: '120px'
353
- },
354
- {
355
- title: 'Average Rating',
356
- render: (question: SurveyQuestion) => {
357
- const stats = question._id ? questionStats[question._id] : null;
358
- return (
359
- <Box direction="vertical" gap="3px">
360
- <Text size="medium" weight="bold">
361
- {stats?.averageRating || 0}
362
- </Text>
363
- <Text size="tiny" secondary>
364
- out of {question.maxRating}
365
- </Text>
366
- </Box>
367
- );
368
- },
369
- width: '120px'
370
- },
371
- {
372
- title: 'Created',
373
- render: (question: SurveyQuestion) => (
374
- <Text size="small">
375
- {question._createdDate ? new Date(question._createdDate).toLocaleDateString() : ''}
376
- </Text>
377
- ),
378
- width: '100px'
379
- },
380
- {
381
- title: 'Actions',
382
- render: (question: SurveyQuestion) => (
383
- <TableActionCell
384
- primaryAction={{
385
- text: 'Edit',
386
- onClick: () => openModal(question)
387
- }}
388
- secondaryActions={[
389
- {
390
- text: question.isActive ? 'Deactivate' : 'Activate',
391
- icon: question.isActive ? <Icons.Hidden /> : <Icons.Visible />,
392
- onClick: () => toggleQuestionStatus(question)
393
- },
394
- {
395
- text: 'Delete',
396
- icon: <Icons.Delete />,
397
- onClick: () => {
398
- if (question._id) {
399
- handleDelete(question._id, question.questionText);
400
- }
401
- }
402
- }
403
- ]}
404
- />
405
- ),
406
- width: '120px'
407
- }
408
- ];
142
+ const totalResponses = Object.values(questionStats).reduce(
143
+ (sum, stats) => sum + stats.totalResponses,
144
+ 0
145
+ );
146
+ const activeQuestions = questions.filter((q) => q.isActive).length;
409
147
 
410
148
  if (loading) {
411
- return (
412
- <WixDesignSystemProvider features={{ newColorsBranding: true }}>
413
- <Page height="100vh">
414
- <Page.Header title="Survey Manager" />
415
- <Page.Content>
416
- <Box align="center" verticalAlign="middle" height="50vh">
417
- <Loader text="Loading survey questions..." />
418
- </Box>
419
- </Page.Content>
420
- </Page>
421
- </WixDesignSystemProvider>
422
- );
149
+ return <PageLoader title="Survey Manager" message="Loading survey questions..." />;
423
150
  }
424
151
 
425
152
  return (
426
- <WixDesignSystemProvider features={{ newColorsBranding: true }}>
427
- <Page height="100vh">
428
- <Page.Header
429
- title="Survey Manager"
430
- subtitle="Create and manage rating survey questions, view aggregated results"
431
- actionsBar={
432
- <Button
433
- onClick={() => openModal()}
434
- prefixIcon={<Icons.Add />}
435
- >
436
- Add Question
437
- </Button>
438
- }
439
- />
440
- <Page.Content>
441
- {questions.length === 0 ? (
442
- <EmptyState
443
- title="No survey questions yet"
444
- subtitle="Create your first rating question to start collecting feedback from visitors"
445
- skin="page"
446
- >
447
- <Button
448
- onClick={() => openModal()}
449
- prefixIcon={<Icons.Add />}
450
- >
451
- Create First Question
452
- </Button>
453
- </EmptyState>
454
- ) : (
455
- <>
456
- {/* Summary Cards */}
457
- <Box gap="24px" marginBottom="24px">
458
- <Card>
459
- <Card.Content>
460
- <Box direction="vertical" gap="6px">
461
- <Heading size="small">Total Questions</Heading>
462
- <Text size="medium" weight="bold">{questions.length}</Text>
463
- </Box>
464
- </Card.Content>
465
- </Card>
466
- <Card>
467
- <Card.Content>
468
- <Box direction="vertical" gap="6px">
469
- <Heading size="small">Active Questions</Heading>
470
- <Text size="medium" weight="bold">
471
- {questions.filter(q => q.isActive).length}
472
- </Text>
473
- </Box>
474
- </Card.Content>
475
- </Card>
476
- <Card>
477
- <Card.Content>
478
- <Box direction="vertical" gap="6px">
479
- <Heading size="small">Total Responses</Heading>
480
- <Text size="medium" weight="bold">
481
- {Object.values(questionStats).reduce((sum, stats) => sum + stats.totalResponses, 0)}
482
- </Text>
483
- </Box>
484
- </Card.Content>
485
- </Card>
486
- </Box>
487
-
488
- {/* Questions Table */}
489
- <Table data={questions} columns={columns}>
490
- <TableToolbar>
491
- <TableToolbar.ItemGroup position="start">
492
- <TableToolbar.Item>
493
- <TableToolbar.Title>Survey Questions</TableToolbar.Title>
494
- </TableToolbar.Item>
495
- </TableToolbar.ItemGroup>
496
- </TableToolbar>
497
- <Table.Content />
498
- </Table>
499
- </>
500
- )}
501
- </Page.Content>
502
- </Page>
503
-
504
- {/* Add/Edit Question Modal */}
505
- <Modal isOpen={isModalOpen} onRequestClose={closeModal}>
506
- <CustomModalLayout
507
- primaryButtonText="Save"
508
- secondaryButtonText="Cancel"
509
- onCloseButtonClick={closeModal}
510
- primaryButtonOnClick={handleSave}
511
- secondaryButtonOnClick={closeModal}
512
- title={`${editingQuestion ? 'Edit' : 'Add'} Survey Question`}
513
- content={
514
- <Layout gap="24px">
515
- <Cell span={12}>
516
- <FormField label="Question Text" required>
517
- <Input
518
- value={formData.questionText}
519
- onChange={(e) => setFormData({ ...formData, questionText: e.target.value })}
520
- placeholder="How would you rate our service?"
521
- />
522
- </FormField>
523
- </Cell>
524
- <Cell span={6}>
525
- <FormField label="Maximum Rating">
526
- <Input
527
- type="number"
528
- value={formData.maxRating.toString()}
529
- onChange={(e) => setFormData({ ...formData, maxRating: Math.max(1, Math.min(10, Number(e.target.value))) })}
530
- min={1}
531
- max={10}
532
- />
533
- </FormField>
534
- </Cell>
535
- <Cell span={6}>
536
- <FormField label="Active" labelPlacement="right" stretchContent={false}>
537
- <ToggleSwitch
538
- checked={formData.isActive}
539
- onChange={() => setFormData({ ...formData, isActive: !formData.isActive })}
540
- />
541
- </FormField>
542
- </Cell>
543
- </Layout>
544
- }
545
- />
546
- </Modal>
547
- </WixDesignSystemProvider>
153
+ <SurveyPageLayout
154
+ questions={questions}
155
+ questionStats={questionStats}
156
+ activeQuestions={activeQuestions}
157
+ totalResponses={totalResponses}
158
+ isModalOpen={isModalOpen}
159
+ editingQuestion={editingQuestion}
160
+ formData={formData}
161
+ onOpenModal={openModal}
162
+ onCloseModal={closeModal}
163
+ onFormChange={setFormData}
164
+ onSave={handleSave}
165
+ onDelete={handleDelete}
166
+ onToggleStatus={handleToggleStatus}
167
+ />
548
168
  );
549
169
  };
550
170
 
551
- export default SurveyManager;
171
+ export default SurveyManager;
@@ -0,0 +1,28 @@
1
+ import type { items } from '@wix/data';
2
+
3
+ export type WixDataItem = items.WixDataItem;
4
+
5
+ export interface SurveyQuestion extends WixDataItem {
6
+ questionText: string;
7
+ maxRating: number;
8
+ isActive: boolean;
9
+ }
10
+
11
+ export interface SurveyResponse extends WixDataItem {
12
+ questionId: string;
13
+ rating: number;
14
+ submittedAt: Date;
15
+ }
16
+
17
+ export interface QuestionStats {
18
+ totalResponses: number;
19
+ averageRating: number;
20
+ ratingDistribution: { [rating: number]: number };
21
+ }
22
+
23
+ export interface QuestionFormData {
24
+ questionText: string;
25
+ maxRating: number;
26
+ isActive: boolean;
27
+ }
28
+
package/dist/out.js CHANGED
@@ -64620,7 +64620,14 @@ var require_load_examples = __commonJS({
64620
64620
  description: "A dashboard app that allows administrators to create and manage rating (1-5) survey questions and view aggregated results",
64621
64621
  files: {
64622
64622
  [types_1.ExtensionType.DASHBOARD_PAGE]: [
64623
- "survey-manager/src/dashboard/pages/page.tsx"
64623
+ "survey-manager/src/dashboard/pages/page.tsx",
64624
+ "survey-manager/src/dashboard/pages/components/PageLoader.tsx",
64625
+ "survey-manager/src/dashboard/pages/components/QuestionModal.tsx",
64626
+ "survey-manager/src/dashboard/pages/components/QuestionsTable.tsx",
64627
+ "survey-manager/src/dashboard/pages/components/SurveyPageLayout.tsx",
64628
+ "survey-manager/src/dashboard/pages/components/SurveyStats.tsx",
64629
+ "survey-manager/src/dashboard/pages/apis.ts",
64630
+ "survey-manager/src/dashboard/pages/types.ts"
64624
64631
  ]
64625
64632
  }
64626
64633
  },
@@ -65312,12 +65319,12 @@ var require_dashboard_page_prompt = __commonJS({
65312
65319
  "use strict";
65313
65320
  Object.defineProperty(exports2, "__esModule", { value: true });
65314
65321
  exports2.dashboardPagePrompt = void 0;
65315
- var types_impl_1 = require_types_impl();
65322
+ var types_1 = require_types_impl();
65316
65323
  var dashboard_page_instructions_1 = require_dashboard_page_instructions();
65317
65324
  var CodeGenerationSystemPromptBuilder_1 = require_CodeGenerationSystemPromptBuilder();
65318
65325
  var dashboardPagePrompt = async ({ useData, useApiSpec, useDynamicParameters, apiNames, useIteration }) => {
65319
65326
  const systemPrompt = (0, CodeGenerationSystemPromptBuilder_1.codeGenerationSystemPromptBuilder)({
65320
- agentType: types_impl_1.ExtensionType.DASHBOARD_PAGE,
65327
+ agentType: types_1.ExtensionType.DASHBOARD_PAGE,
65321
65328
  apiNames,
65322
65329
  useData,
65323
65330
  useIteration
@@ -65714,12 +65721,12 @@ var require_site_component_prompt = __commonJS({
65714
65721
  "use strict";
65715
65722
  Object.defineProperty(exports2, "__esModule", { value: true });
65716
65723
  exports2.siteComponentPrompt = void 0;
65717
- var types_impl_1 = require_types_impl();
65724
+ var types_1 = require_types_impl();
65718
65725
  var site_component_instructions_1 = require_site_component_instructions();
65719
65726
  var CodeGenerationSystemPromptBuilder_1 = require_CodeGenerationSystemPromptBuilder();
65720
65727
  var siteComponentPrompt = (apiNames, useData, useIteration) => {
65721
65728
  const siteComponentPromptBuilder = (0, CodeGenerationSystemPromptBuilder_1.codeGenerationSystemPromptBuilder)({
65722
- agentType: types_impl_1.ExtensionType.SITE_COMPONENT,
65729
+ agentType: types_1.ExtensionType.SITE_COMPONENT,
65723
65730
  apiNames,
65724
65731
  useData,
65725
65732
  useIteration
@@ -65841,12 +65848,12 @@ var require_custom_element_prompt = __commonJS({
65841
65848
  "use strict";
65842
65849
  Object.defineProperty(exports2, "__esModule", { value: true });
65843
65850
  exports2.customElementPrompt = void 0;
65844
- var types_impl_1 = require_types_impl();
65851
+ var types_1 = require_types_impl();
65845
65852
  var custom_element_instructions_1 = require_custom_element_instructions();
65846
65853
  var CodeGenerationSystemPromptBuilder_1 = require_CodeGenerationSystemPromptBuilder();
65847
65854
  var customElementPrompt = (apiNames, useData, useIteration) => {
65848
65855
  const systemPrompt = (0, CodeGenerationSystemPromptBuilder_1.codeGenerationSystemPromptBuilder)({
65849
- agentType: types_impl_1.ExtensionType.SITE_WIDGET,
65856
+ agentType: types_1.ExtensionType.SITE_WIDGET,
65850
65857
  apiNames,
65851
65858
  useData,
65852
65859
  useIteration
@@ -66075,12 +66082,12 @@ var require_service_plugin_prompt = __commonJS({
66075
66082
  exports2.servicePluginPrompt = void 0;
66076
66083
  var servicePluginDocLoader_1 = require_servicePluginDocLoader();
66077
66084
  var service_plugin_instructions_1 = require_service_plugin_instructions();
66078
- var types_impl_1 = require_types_impl();
66085
+ var types_1 = require_types_impl();
66079
66086
  var CodeGenerationSystemPromptBuilder_1 = require_CodeGenerationSystemPromptBuilder();
66080
66087
  var servicePluginPrompt = ({ apiNames, useData, useIteration, spiNames = [] }) => {
66081
66088
  const servicePluginDocs = (0, servicePluginDocLoader_1.loadServicePluginDocumentation)(spiNames);
66082
66089
  const servicePluginPromptBuilder = (0, CodeGenerationSystemPromptBuilder_1.codeGenerationSystemPromptBuilder)({
66083
- agentType: types_impl_1.ExtensionType.SERVICE_PLUGIN,
66090
+ agentType: types_1.ExtensionType.SERVICE_PLUGIN,
66084
66091
  apiNames,
66085
66092
  useData,
66086
66093
  useIteration
@@ -66194,12 +66201,12 @@ var require_backend_event_prompt = __commonJS({
66194
66201
  "use strict";
66195
66202
  Object.defineProperty(exports2, "__esModule", { value: true });
66196
66203
  exports2.backendEventPrompt = void 0;
66197
- var types_impl_1 = require_types_impl();
66204
+ var types_1 = require_types_impl();
66198
66205
  var backend_event_instructions_1 = require_backend_event_instructions();
66199
66206
  var CodeGenerationSystemPromptBuilder_1 = require_CodeGenerationSystemPromptBuilder();
66200
66207
  var backendEventPrompt = (apiNames, useData, useIteration) => {
66201
66208
  const backendEventPromptBuilder = (0, CodeGenerationSystemPromptBuilder_1.codeGenerationSystemPromptBuilder)({
66202
- agentType: types_impl_1.ExtensionType.BACKEND_EVENT,
66209
+ agentType: types_1.ExtensionType.BACKEND_EVENT,
66203
66210
  apiNames,
66204
66211
  useData,
66205
66212
  useIteration
@@ -66351,12 +66358,12 @@ var require_backend_api_prompt = __commonJS({
66351
66358
  "use strict";
66352
66359
  Object.defineProperty(exports2, "__esModule", { value: true });
66353
66360
  exports2.backendApiPrompt = void 0;
66354
- var types_impl_1 = require_types_impl();
66361
+ var types_1 = require_types_impl();
66355
66362
  var backend_api_instructions_1 = require_backend_api_instructions();
66356
66363
  var CodeGenerationSystemPromptBuilder_1 = require_CodeGenerationSystemPromptBuilder();
66357
66364
  var backendApiPrompt = (apiNames, useData, useIteration) => {
66358
66365
  const systemPrompt = (0, CodeGenerationSystemPromptBuilder_1.codeGenerationSystemPromptBuilder)({
66359
- agentType: types_impl_1.ExtensionType.BACKEND_API,
66366
+ agentType: types_1.ExtensionType.BACKEND_API,
66360
66367
  apiNames,
66361
66368
  useData,
66362
66369
  useIteration
@@ -66623,14 +66630,14 @@ var require_embedded_script_prompt = __commonJS({
66623
66630
  Object.defineProperty(exports2, "__esModule", { value: true });
66624
66631
  exports2.embeddedScriptPrompt = void 0;
66625
66632
  var dynamicParameters_1 = require_dynamicParameters2();
66626
- var types_impl_1 = require_types_impl();
66633
+ var types_1 = require_types_impl();
66627
66634
  var embedded_script_instructions_1 = require_embedded_script_instructions();
66628
66635
  var CodeGenerationSystemPromptBuilder_1 = require_CodeGenerationSystemPromptBuilder();
66629
66636
  var embeddedScriptPrompt = (hasDynamicParameters, apiNames, useData, useIteration) => {
66630
66637
  const embeddedScriptImplementationGuidelines = hasDynamicParameters ? `${embedded_script_instructions_1.embeddedScriptInstructions.embeddedScriptImplementationGuidelines}
66631
66638
  ${(0, dynamicParameters_1.dynamicParametersPrompt)()}` : embedded_script_instructions_1.embeddedScriptInstructions.embeddedScriptImplementationGuidelines;
66632
66639
  const systemPrompt = (0, CodeGenerationSystemPromptBuilder_1.codeGenerationSystemPromptBuilder)({
66633
- agentType: types_impl_1.ExtensionType.EMBEDDED_SCRIPT,
66640
+ agentType: types_1.ExtensionType.EMBEDDED_SCRIPT,
66634
66641
  apiNames,
66635
66642
  useData,
66636
66643
  useIteration
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/ditto-codegen-public",
3
- "version": "1.0.178",
3
+ "version": "1.0.180",
4
4
  "description": "AI-powered Wix CLI app generator - standalone executable",
5
5
  "scripts": {
6
6
  "build": "node build.mjs",
@@ -24,5 +24,5 @@
24
24
  "@wix/ditto-codegen": "1.0.0",
25
25
  "esbuild": "^0.25.9"
26
26
  },
27
- "falconPackageHash": "d5724027b8c912830720b4abdda14f6a232e7dbf770df1d3b8b3f99c"
27
+ "falconPackageHash": "e8dba8e74db8a8a39dce94ec11ac6c277c9fa845178e72670a580574"
28
28
  }
@@ -1,18 +0,0 @@
1
- <svg width="166" height="64" viewBox="0 0 166 64" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <g clip-path="url(#clip0_14809_9463)">
3
- <path
4
- d="M165.304 0H156.173C153.64 0 151.273 1.25433 149.85 3.35199L137.639 21.3662C137.313 21.844 136.608 21.844 136.283 21.3662L124.071 3.35199C122.651 1.25433 120.281 0 117.748 0H108.617L130.371 32.0894L108.737 64H117.868C120.401 64 122.769 62.7457 124.192 60.648L136.283 42.8126C136.608 42.3349 137.313 42.3349 137.639 42.8126L149.73 60.648C151.15 62.7457 153.52 64 156.053 64H165.184L143.551 32.0894L165.304 0Z"
5
- fill="black" />
6
- <path
7
- d="M89.8281 6.54652V64H94.1922C97.8088 64 100.74 61.0697 100.74 57.4535V0H96.3755C92.7588 0 89.8281 2.93032 89.8281 6.54652Z"
8
- fill="black" />
9
- <path
10
- d="M81.8276 0H77.944C73.6681 0 69.9633 2.95701 69.0158 7.12564L60.3278 45.3185L52.7234 9.66632C51.3168 3.0771 44.5559 -1.36641 37.6375 0.544431C33.2307 1.76139 29.9637 5.48434 29.0108 9.95455L21.4839 45.2705L12.8118 7.12831C11.8616 2.95968 8.15687 0 3.88092 0H0L14.5548 63.9973H20.0692C25.0738 63.9973 29.3978 60.4986 30.4415 55.604L39.7461 11.9401C39.8608 11.3984 40.3466 11.006 40.8991 11.006C41.4516 11.006 41.9374 11.3984 42.0522 11.9401L51.3648 55.6067C52.4084 60.5012 56.7324 63.9973 61.7371 63.9973H67.2702L81.8276 0Z"
11
- fill="black" />
12
- </g>
13
- <defs>
14
- <clipPath id="clip0_14809_9463">
15
- <rect width="165.305" height="64" fill="white" />
16
- </clipPath>
17
- </defs>
18
- </svg>
@@ -1,10 +0,0 @@
1
- import { app, extensions } from '@wix/astro/builders';
2
-
3
- export default app().use(
4
- extensions.dashboardPage({
5
- component: './dashboard/pages/page.tsx',
6
- id: '4344c4a2-1864-4587-87e9-5e4109b16999',
7
- routePath: 'survey-manager',
8
- title: 'Survey Manager',
9
- })
10
- );