accomadesc 0.0.14 → 0.1.0
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/AccoCard.svelte.d.ts +2 -1
- package/dist/AccoDescription.svelte.d.ts +2 -1
- package/dist/AmenitiesCore.svelte +2 -2
- package/dist/AmenitiesCore.svelte.d.ts +2 -1
- package/dist/BookingRequest.svelte +272 -0
- package/dist/BookingRequest.svelte.d.ts +5 -0
- package/dist/Calendar.svelte +25 -11
- package/dist/Calendar.svelte.d.ts +2 -1
- package/dist/CalendarAvailable.svelte +11 -18
- package/dist/CalendarAvailable.svelte.d.ts +2 -1
- package/dist/CalendarGrid.svelte +22 -0
- package/dist/CalendarGrid.svelte.d.ts +5 -0
- package/dist/CalendarRows.svelte +22 -0
- package/dist/CalendarRows.svelte.d.ts +5 -0
- package/dist/ContactForm.svelte +180 -0
- package/dist/ContactForm.svelte.d.ts +5 -0
- package/dist/Photo.svelte.d.ts +2 -1
- package/dist/PhotoGallery.svelte +89 -35
- package/dist/PhotoGallery.svelte.d.ts +2 -1
- package/dist/Pricing.svelte.d.ts +2 -1
- package/dist/PricingShort.svelte.d.ts +2 -1
- package/dist/Section.svelte.d.ts +2 -1
- package/dist/Text.svelte.d.ts +2 -1
- package/dist/Weather.svelte +1 -2
- package/dist/Weather.svelte.d.ts +2 -1
- package/dist/basic/Avatar.svelte.d.ts +3 -2
- package/dist/basic/Button.svelte +6 -3
- package/dist/basic/Button.svelte.d.ts +4 -3
- package/dist/basic/Icon.svelte.d.ts +3 -2
- package/dist/basic/Notes.svelte +83 -0
- package/dist/basic/Notes.svelte.d.ts +7 -0
- package/dist/basic/Spinner.svelte.d.ts +3 -2
- package/dist/basic/TextInput.svelte.d.ts +3 -2
- package/dist/helpers/debounce.d.ts +7 -0
- package/dist/helpers/debounce.js +49 -0
- package/dist/helpers/iCSEventExample.ics +14 -0
- package/dist/helpers/normalizeDate.d.ts +2 -0
- package/dist/helpers/normalizeDate.js +53 -0
- package/dist/helpers/readICS.d.ts +7 -0
- package/dist/helpers/readICS.js +94 -0
- package/dist/names/gen.js +3 -3
- package/dist/occuplan/OccuPlanAvailableInfo.svelte +38 -0
- package/dist/occuplan/OccuPlanAvailableInfo.svelte.d.ts +12 -0
- package/dist/occuplan/OccuPlanGrid.svelte +356 -0
- package/dist/occuplan/OccuPlanGrid.svelte.d.ts +13 -0
- package/dist/occuplan/OccuPlanPicker.svelte +559 -0
- package/dist/occuplan/OccuPlanPicker.svelte.d.ts +16 -0
- package/dist/occuplan/OccuPlanRows.svelte +360 -0
- package/dist/occuplan/OccuPlanRows.svelte.d.ts +13 -0
- package/dist/occuplan/OccuPlanWrapper.svelte +113 -0
- package/dist/occuplan/OccuPlanWrapper.svelte.d.ts +5 -0
- package/dist/occuplan/state.svelte.d.ts +90 -0
- package/dist/occuplan/state.svelte.js +383 -0
- package/dist/svg/ExtLinkSVG.svelte.d.ts +3 -2
- package/dist/svg/LinkSVG.svelte.d.ts +3 -2
- package/dist/types.d.ts +75 -4
- package/dist/types.js +20 -0
- package/package.json +64 -61
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type AccoCardContent, type I18nFacade } from './types.js';
|
|
2
|
-
|
|
2
|
+
type $$ComponentProps = AccoCardContent & I18nFacade;
|
|
3
|
+
declare const AccoCard: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
3
4
|
type AccoCard = ReturnType<typeof AccoCard>;
|
|
4
5
|
export default AccoCard;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AccoDescriptionContent, I18nFacade } from './types.js';
|
|
2
|
-
|
|
2
|
+
type $$ComponentProps = AccoDescriptionContent & I18nFacade;
|
|
3
|
+
declare const AccoDescription: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
3
4
|
type AccoDescription = ReturnType<typeof AccoDescription>;
|
|
4
5
|
export default AccoDescription;
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
let formattedSize: string = $derived(formatFunc ? formatFunc('size', { size: size }) : `${size}`);
|
|
38
38
|
</script>
|
|
39
39
|
|
|
40
|
-
<div class="
|
|
40
|
+
<div class="amenities-wrapper">
|
|
41
41
|
<div class="element-wrapper">
|
|
42
42
|
<AreaSvg size="2rem" />
|
|
43
43
|
<div>
|
|
@@ -151,7 +151,7 @@
|
|
|
151
151
|
</div>
|
|
152
152
|
|
|
153
153
|
<style>
|
|
154
|
-
.
|
|
154
|
+
.amenities-wrapper {
|
|
155
155
|
background-color: var(--main-bg-color);
|
|
156
156
|
color: var(--main-font-color);
|
|
157
157
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AmenitiesCoreContent, I18nFacade } from './types.js';
|
|
2
|
-
|
|
2
|
+
type $$ComponentProps = AmenitiesCoreContent & I18nFacade;
|
|
3
|
+
declare const AmenitiesCore: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
3
4
|
type AmenitiesCore = ReturnType<typeof AmenitiesCore>;
|
|
4
5
|
export default AmenitiesCore;
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { BookingRequestContent, I18nFacade } from './types.js';
|
|
3
|
+
import { getContext } from 'svelte';
|
|
4
|
+
import Button from './basic/Button.svelte';
|
|
5
|
+
import Notes from './basic/Notes.svelte';
|
|
6
|
+
import Spinner from './basic/Spinner.svelte';
|
|
7
|
+
import TextInput from './basic/TextInput.svelte';
|
|
8
|
+
import { OCCUPATION_STATE, OccupationState } from './occuplan/state.svelte.ts';
|
|
9
|
+
import OccuPlanPicker from './occuplan/OccuPlanPicker.svelte';
|
|
10
|
+
import { slide } from 'svelte/transition';
|
|
11
|
+
import type { DateTime } from 'luxon';
|
|
12
|
+
|
|
13
|
+
const {
|
|
14
|
+
endpoint,
|
|
15
|
+
acco,
|
|
16
|
+
messageLabel,
|
|
17
|
+
calUrl,
|
|
18
|
+
userID,
|
|
19
|
+
nameLabel,
|
|
20
|
+
emailLabel,
|
|
21
|
+
dateEntryLabel,
|
|
22
|
+
explainer,
|
|
23
|
+
successfullySentText,
|
|
24
|
+
sentErroredText,
|
|
25
|
+
submitText,
|
|
26
|
+
invalidText,
|
|
27
|
+
maxCharsAllowed = 300,
|
|
28
|
+
translateFunc,
|
|
29
|
+
formatDateFunc,
|
|
30
|
+
}: BookingRequestContent & I18nFacade = $props();
|
|
31
|
+
|
|
32
|
+
let name = $state('');
|
|
33
|
+
let email = $state('');
|
|
34
|
+
let message = $state('');
|
|
35
|
+
let arrival: DateTime | undefined = $state();
|
|
36
|
+
let leave: DateTime | undefined = $state();
|
|
37
|
+
let disabled = $state(false);
|
|
38
|
+
let inputDatesEngaged = $state(false);
|
|
39
|
+
|
|
40
|
+
let currentCharsCount = $derived(message.length);
|
|
41
|
+
let showMaxCharsMessage = $derived(currentCharsCount > maxCharsAllowed - 50);
|
|
42
|
+
let canSubmit: boolean = $derived(
|
|
43
|
+
name.length > 0 &&
|
|
44
|
+
email.length > 0 &&
|
|
45
|
+
message.length <= maxCharsAllowed &&
|
|
46
|
+
!!arrival &&
|
|
47
|
+
!!leave,
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
let errored = $state(false);
|
|
51
|
+
let successfullySent = $state(false);
|
|
52
|
+
let sending = $state(false);
|
|
53
|
+
|
|
54
|
+
//https://popnapdkcdnabruxkjti.supabase.co/storage/v1/object/public/ical/81e66599-ac3c-4ad6-b261-fceeb784f9e9/050edcb4-680e-4542-96df-3ae4a2af89a5
|
|
55
|
+
|
|
56
|
+
const url = calUrl; //`${accomadeBaseUrl}/${userID}/${acco.path}`;
|
|
57
|
+
const oStateID = `i-${url}-${OCCUPATION_STATE}`;
|
|
58
|
+
let occupationState: OccupationState = $state(getContext(oStateID));
|
|
59
|
+
let invalid = $derived(
|
|
60
|
+
occupationState && arrival && leave ? occupationState.validRequest(arrival, leave) : false,
|
|
61
|
+
);
|
|
62
|
+
const messageChanged = (value: string) => {
|
|
63
|
+
message = value;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const abortDateInput = () => {
|
|
67
|
+
inputDatesEngaged = false;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const engageDateInput = () => {
|
|
71
|
+
inputDatesEngaged = true;
|
|
72
|
+
};
|
|
73
|
+
const dateSelected = (a: DateTime, l: DateTime) => {
|
|
74
|
+
arrival = a;
|
|
75
|
+
leave = l;
|
|
76
|
+
inputDatesEngaged = false;
|
|
77
|
+
};
|
|
78
|
+
const dateDeleted = () => {
|
|
79
|
+
arrival = undefined;
|
|
80
|
+
leave = undefined;
|
|
81
|
+
inputDatesEngaged = false;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const createRequest = async (e: SubmitEvent) => {
|
|
85
|
+
sending = true;
|
|
86
|
+
e.preventDefault();
|
|
87
|
+
try {
|
|
88
|
+
const response = await fetch(endpoint, {
|
|
89
|
+
method: 'POST',
|
|
90
|
+
headers: {
|
|
91
|
+
'Content-Type': 'application/json',
|
|
92
|
+
},
|
|
93
|
+
body: JSON.stringify({
|
|
94
|
+
userID: userID,
|
|
95
|
+
acco: acco.path,
|
|
96
|
+
guestEmail: email,
|
|
97
|
+
guestName: name,
|
|
98
|
+
message: message,
|
|
99
|
+
arrival: arrival?.toISO(),
|
|
100
|
+
leave: leave?.toISO(),
|
|
101
|
+
}),
|
|
102
|
+
});
|
|
103
|
+
if (response.status != 201) {
|
|
104
|
+
errored = true;
|
|
105
|
+
console.log('Error sending mail', response.status, response.statusText);
|
|
106
|
+
} else {
|
|
107
|
+
successfullySent = true;
|
|
108
|
+
}
|
|
109
|
+
} catch (e) {
|
|
110
|
+
errored = true;
|
|
111
|
+
console.log('Error sending request', e);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
sending = false;
|
|
115
|
+
setTimeout(() => {
|
|
116
|
+
errored = false;
|
|
117
|
+
successfullySent = false;
|
|
118
|
+
}, 15000);
|
|
119
|
+
|
|
120
|
+
return false;
|
|
121
|
+
};
|
|
122
|
+
</script>
|
|
123
|
+
|
|
124
|
+
<div class="wrapper">
|
|
125
|
+
{#if explainer}
|
|
126
|
+
<div class="explainer">{@html translateFunc ? translateFunc(explainer) : ''}</div>
|
|
127
|
+
{/if}
|
|
128
|
+
<form onsubmit={createRequest}>
|
|
129
|
+
<input type="hidden" value={userID} />
|
|
130
|
+
<label class:disabled>
|
|
131
|
+
{@html translateFunc ? translateFunc(nameLabel) : 'Name'}:
|
|
132
|
+
<TextInput type="text" marginForMessage={false} bind:value={name} enabled={!disabled} />
|
|
133
|
+
</label>
|
|
134
|
+
<label class:disabled>
|
|
135
|
+
{@html translateFunc ? translateFunc(emailLabel) : 'Email'}:
|
|
136
|
+
<TextInput type="email" marginForMessage={false} bind:value={email} enabled={!disabled} />
|
|
137
|
+
</label>
|
|
138
|
+
<div style="display:flex;">
|
|
139
|
+
<span class:disabled>
|
|
140
|
+
{@html translateFunc ? translateFunc(dateEntryLabel) : 'Vacation Dates'}:
|
|
141
|
+
</span>
|
|
142
|
+
<div class="date-input-wrapper">
|
|
143
|
+
{#if inputDatesEngaged}
|
|
144
|
+
<div transition:slide style="min-width: 32rem;" class="picker-wrapper">
|
|
145
|
+
<OccuPlanPicker {arrival} {leave} {url} aborted={abortDateInput} {dateSelected} />
|
|
146
|
+
</div>
|
|
147
|
+
{/if}
|
|
148
|
+
<div class="date-input-display-wrapper" id="engage-date-buttons">
|
|
149
|
+
<Button
|
|
150
|
+
iconName="edit"
|
|
151
|
+
size={1.8}
|
|
152
|
+
clicked={engageDateInput}
|
|
153
|
+
text={arrival && leave && formatDateFunc
|
|
154
|
+
? `${formatDateFunc(arrival)} - ${formatDateFunc(leave)}`
|
|
155
|
+
: ''}
|
|
156
|
+
/>
|
|
157
|
+
{#if arrival && leave}
|
|
158
|
+
<Button iconName="delete" size={1.8} clicked={dateDeleted} />
|
|
159
|
+
{/if}
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
</div>
|
|
163
|
+
<label class="row-label"
|
|
164
|
+
><div class:disabled>
|
|
165
|
+
{@html translateFunc
|
|
166
|
+
? translateFunc(messageLabel)
|
|
167
|
+
: 'Your Message'}{#if showMaxCharsMessage}<span class="max-chars-message"
|
|
168
|
+
> ({currentCharsCount}/{maxCharsAllowed})</span
|
|
169
|
+
>{/if}:
|
|
170
|
+
</div>
|
|
171
|
+
<Notes {disabled} changed={messageChanged} />
|
|
172
|
+
</label>
|
|
173
|
+
|
|
174
|
+
{#if successfullySent}
|
|
175
|
+
<div class="success">
|
|
176
|
+
{translateFunc ? translateFunc(successfullySentText) : 'Successfully Sent Email'}
|
|
177
|
+
</div>
|
|
178
|
+
{/if}
|
|
179
|
+
{#if errored}
|
|
180
|
+
<div class="error">
|
|
181
|
+
{translateFunc ? translateFunc(sentErroredText) : 'Error Occurred Sending Email'}
|
|
182
|
+
</div>
|
|
183
|
+
{/if}
|
|
184
|
+
{#if invalid}
|
|
185
|
+
<div class="error">
|
|
186
|
+
{translateFunc ? translateFunc(invalidText) : 'Dates Are Not Available'}
|
|
187
|
+
</div>
|
|
188
|
+
{/if}
|
|
189
|
+
<div class="button-wrapper">
|
|
190
|
+
<Button
|
|
191
|
+
enabled={canSubmit && !disabled}
|
|
192
|
+
text={translateFunc ? translateFunc(submitText) : 'Submit'}
|
|
193
|
+
type="submit"
|
|
194
|
+
/>
|
|
195
|
+
</div>
|
|
196
|
+
</form>
|
|
197
|
+
{#if sending}
|
|
198
|
+
<Spinner />
|
|
199
|
+
{/if}
|
|
200
|
+
</div>
|
|
201
|
+
|
|
202
|
+
<style>
|
|
203
|
+
.wrapper {
|
|
204
|
+
background-color: var(--main-bg-color);
|
|
205
|
+
color: var(--main-font-color);
|
|
206
|
+
|
|
207
|
+
width: 100%;
|
|
208
|
+
display: flex;
|
|
209
|
+
|
|
210
|
+
padding: 1rem;
|
|
211
|
+
margin: 1rem;
|
|
212
|
+
:global(*) {
|
|
213
|
+
color: var(--main-font-color);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.date-input-wrapper {
|
|
218
|
+
width: 100%;
|
|
219
|
+
display: flex;
|
|
220
|
+
justify-content: flex-end;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.date-input-display-wrapper {
|
|
224
|
+
display: flex;
|
|
225
|
+
justify-content: flex-end;
|
|
226
|
+
align-items: center;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.picker-wrapper {
|
|
230
|
+
position: absolute;
|
|
231
|
+
z-index: 9999;
|
|
232
|
+
background-color: var(--main-bg-color);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
form {
|
|
236
|
+
width: 100%;
|
|
237
|
+
display: flex;
|
|
238
|
+
flex-direction: column;
|
|
239
|
+
gap: 0.5rem;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
label {
|
|
243
|
+
display: flex;
|
|
244
|
+
gap: 1rem;
|
|
245
|
+
align-items: center;
|
|
246
|
+
justify-content: space-between;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.row-label {
|
|
250
|
+
flex-direction: column;
|
|
251
|
+
gap: 0.2rem;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.max-chars-message {
|
|
255
|
+
font-weight: bolder;
|
|
256
|
+
color: var(--alert-font-color);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.success {
|
|
260
|
+
color: var(--accept-font-color);
|
|
261
|
+
font-weight: bolder;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.error {
|
|
265
|
+
color: var(--alert-font-color);
|
|
266
|
+
font-weight: bolder;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.disabled {
|
|
270
|
+
color: var(--font-disabled-color);
|
|
271
|
+
}
|
|
272
|
+
</style>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { BookingRequestContent, I18nFacade } from './types.js';
|
|
2
|
+
type $$ComponentProps = BookingRequestContent & I18nFacade;
|
|
3
|
+
declare const BookingRequest: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
4
|
+
type BookingRequest = ReturnType<typeof BookingRequest>;
|
|
5
|
+
export default BookingRequest;
|
package/dist/Calendar.svelte
CHANGED
|
@@ -1,21 +1,35 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import
|
|
3
|
-
import Spinner from './basic/Spinner.svelte';
|
|
2
|
+
import OccuPlanWrapper from './occuplan/OccuPlanWrapper.svelte';
|
|
4
3
|
import type { CalendarContent, I18nFacade } from './types.js';
|
|
5
4
|
|
|
6
|
-
let {
|
|
7
|
-
|
|
5
|
+
let {
|
|
6
|
+
url,
|
|
7
|
+
calendarTranslation,
|
|
8
|
+
toggleGridOffset,
|
|
9
|
+
gridMonthNumbers,
|
|
10
|
+
gridFirstMonth,
|
|
11
|
+
gridMaxWidth,
|
|
12
|
+
toggleRowsOffset,
|
|
13
|
+
rowsMonthNumbers,
|
|
14
|
+
rowsFirstMonth,
|
|
15
|
+
rowsMaxWidth,
|
|
16
|
+
translateFunc,
|
|
17
|
+
}: CalendarContent & I18nFacade = $props();
|
|
8
18
|
</script>
|
|
9
19
|
|
|
10
20
|
<div class="cal-wrapper">
|
|
11
|
-
{#if calLoading}
|
|
12
|
-
<Spinner />
|
|
13
|
-
{/if}
|
|
14
21
|
<OccuPlanWrapper
|
|
15
|
-
|
|
16
|
-
{
|
|
17
|
-
|
|
18
|
-
|
|
22
|
+
{url}
|
|
23
|
+
{toggleGridOffset}
|
|
24
|
+
gridNumberOfMonths={gridMonthNumbers}
|
|
25
|
+
{gridFirstMonth}
|
|
26
|
+
{gridMaxWidth}
|
|
27
|
+
{toggleRowsOffset}
|
|
28
|
+
rowsNumberOfMonths={rowsMonthNumbers}
|
|
29
|
+
{rowsFirstMonth}
|
|
30
|
+
{rowsMaxWidth}
|
|
31
|
+
header={translateFunc ? translateFunc('calendarHeader') : ''}
|
|
32
|
+
{...calendarTranslation}
|
|
19
33
|
/>
|
|
20
34
|
</div>
|
|
21
35
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CalendarContent, I18nFacade } from './types.js';
|
|
2
|
-
|
|
2
|
+
type $$ComponentProps = CalendarContent & I18nFacade;
|
|
3
|
+
declare const Calendar: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
3
4
|
type Calendar = ReturnType<typeof Calendar>;
|
|
4
5
|
export default Calendar;
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import
|
|
2
|
+
import OccuPlanAvailableInfo from './occuplan/OccuPlanAvailableInfo.svelte';
|
|
3
3
|
import { DateTime } from 'luxon';
|
|
4
|
-
import Spinner from './basic/Spinner.svelte';
|
|
5
4
|
import type { CalendarAvailableContent, I18nFacade } from './types.js';
|
|
5
|
+
import { type AvailableSpans } from './occuplan/state.svelte.ts';
|
|
6
6
|
|
|
7
7
|
let {
|
|
8
|
-
|
|
8
|
+
url,
|
|
9
9
|
search = [3, 7, 14],
|
|
10
10
|
maxFutureDate = DateTime.now().plus({ years: 2 }).toISO(),
|
|
11
11
|
formatFunc,
|
|
12
12
|
translateFunc,
|
|
13
13
|
}: CalendarAvailableContent & I18nFacade = $props();
|
|
14
|
-
let calLoading = $state(true);
|
|
15
14
|
|
|
16
15
|
let availHeader = $derived(translateFunc ? translateFunc('availability') : '[AVAILABILITY]');
|
|
17
16
|
|
|
@@ -33,21 +32,15 @@
|
|
|
33
32
|
<div class="cal-wrapper">
|
|
34
33
|
<h3>{availHeader}</h3>
|
|
35
34
|
|
|
36
|
-
<OccuPlanAvailableInfo
|
|
37
|
-
{
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
<li>{formatAvailability(av[s], s)}</li>
|
|
45
|
-
{/each}
|
|
46
|
-
</ul>
|
|
35
|
+
<OccuPlanAvailableInfo {search} {url}>
|
|
36
|
+
{#snippet children(av: AvailableSpans)}
|
|
37
|
+
<ul>
|
|
38
|
+
{#each search as s}
|
|
39
|
+
<li>{formatAvailability(av[s], s)}</li>
|
|
40
|
+
{/each}
|
|
41
|
+
</ul>
|
|
42
|
+
{/snippet}
|
|
47
43
|
</OccuPlanAvailableInfo>
|
|
48
|
-
{#if calLoading}
|
|
49
|
-
<Spinner />
|
|
50
|
-
{/if}
|
|
51
44
|
</div>
|
|
52
45
|
|
|
53
46
|
<style>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CalendarAvailableContent, I18nFacade } from './types.js';
|
|
2
|
-
|
|
2
|
+
type $$ComponentProps = CalendarAvailableContent & I18nFacade;
|
|
3
|
+
declare const CalendarAvailable: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
3
4
|
type CalendarAvailable = ReturnType<typeof CalendarAvailable>;
|
|
4
5
|
export default CalendarAvailable;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { CalendarGridContent, I18nFacade } from './types.js';
|
|
3
|
+
import OccuPlanGrid from './occuplan/OccuPlanGrid.svelte';
|
|
4
|
+
|
|
5
|
+
let { url, calendarTranslation, translateFunc }: CalendarGridContent & I18nFacade = $props();
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<div class="cal-wrapper">
|
|
9
|
+
<OccuPlanGrid
|
|
10
|
+
{url}
|
|
11
|
+
header={translateFunc ? translateFunc('calendarHeader') : ''}
|
|
12
|
+
{...calendarTranslation}
|
|
13
|
+
/>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<style>
|
|
17
|
+
.cal-wrapper {
|
|
18
|
+
position: relative;
|
|
19
|
+
display: flex;
|
|
20
|
+
justify-content: center;
|
|
21
|
+
}
|
|
22
|
+
</style>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { CalendarGridContent, I18nFacade } from './types.js';
|
|
2
|
+
type $$ComponentProps = CalendarGridContent & I18nFacade;
|
|
3
|
+
declare const CalendarGrid: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
4
|
+
type CalendarGrid = ReturnType<typeof CalendarGrid>;
|
|
5
|
+
export default CalendarGrid;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { CalendarRowsContent, I18nFacade } from './types.js';
|
|
3
|
+
import OccuPlanRows from './occuplan/OccuPlanRows.svelte';
|
|
4
|
+
|
|
5
|
+
let { url, calendarTranslation, translateFunc }: CalendarRowsContent & I18nFacade = $props();
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<div class="cal-wrapper">
|
|
9
|
+
<OccuPlanRows
|
|
10
|
+
{url}
|
|
11
|
+
header={translateFunc ? translateFunc('calendarHeader') : ''}
|
|
12
|
+
{...calendarTranslation}
|
|
13
|
+
/>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<style>
|
|
17
|
+
.cal-wrapper {
|
|
18
|
+
position: relative;
|
|
19
|
+
display: flex;
|
|
20
|
+
justify-content: center;
|
|
21
|
+
}
|
|
22
|
+
</style>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { CalendarRowsContent, I18nFacade } from './types.js';
|
|
2
|
+
type $$ComponentProps = CalendarRowsContent & I18nFacade;
|
|
3
|
+
declare const CalendarRows: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
4
|
+
type CalendarRows = ReturnType<typeof CalendarRows>;
|
|
5
|
+
export default CalendarRows;
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Spinner from './basic/Spinner.svelte';
|
|
3
|
+
import Button from './basic/Button.svelte';
|
|
4
|
+
import TextInput from './basic/TextInput.svelte';
|
|
5
|
+
import Notes from './basic/Notes.svelte';
|
|
6
|
+
import type { ContactFormContent, I18nFacade } from './types.js';
|
|
7
|
+
|
|
8
|
+
const {
|
|
9
|
+
userID,
|
|
10
|
+
endpoint,
|
|
11
|
+
explainer,
|
|
12
|
+
emailLabel,
|
|
13
|
+
nameLabel,
|
|
14
|
+
questionLabel,
|
|
15
|
+
submitText,
|
|
16
|
+
successfullySentText,
|
|
17
|
+
sentErroredText,
|
|
18
|
+
maxCharsAllowed = 300,
|
|
19
|
+
translateFunc,
|
|
20
|
+
}: ContactFormContent & I18nFacade = $props();
|
|
21
|
+
|
|
22
|
+
let name = $state('');
|
|
23
|
+
let email = $state('');
|
|
24
|
+
let question = $state('');
|
|
25
|
+
let successfullySent = $state(false);
|
|
26
|
+
let sending = $state(false);
|
|
27
|
+
let errored = $state(false);
|
|
28
|
+
|
|
29
|
+
const questionChanged = (value: string) => {
|
|
30
|
+
question = value;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
let currentCharsCount = $derived(question.length);
|
|
34
|
+
let showMaxCharsMessage = $derived(currentCharsCount > maxCharsAllowed - 50);
|
|
35
|
+
let canSubmit: boolean = $derived(
|
|
36
|
+
name.length > 0 &&
|
|
37
|
+
email.length > 0 &&
|
|
38
|
+
question.length > 0 &&
|
|
39
|
+
question.length <= maxCharsAllowed,
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const submitMessage = async (e: Event) => {
|
|
43
|
+
sending = true;
|
|
44
|
+
e.preventDefault();
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
const response = await fetch(endpoint, {
|
|
48
|
+
method: 'POST',
|
|
49
|
+
headers: {
|
|
50
|
+
'Content-Type': 'application/json',
|
|
51
|
+
},
|
|
52
|
+
body: JSON.stringify({
|
|
53
|
+
userID: userID,
|
|
54
|
+
email: email,
|
|
55
|
+
name: name,
|
|
56
|
+
question: question,
|
|
57
|
+
}),
|
|
58
|
+
});
|
|
59
|
+
if (response.status != 201) {
|
|
60
|
+
errored = true;
|
|
61
|
+
console.log('Error sending mail', response.status, response.statusText);
|
|
62
|
+
} else {
|
|
63
|
+
successfullySent = true;
|
|
64
|
+
}
|
|
65
|
+
} catch (e) {
|
|
66
|
+
console.log('An error occurred:', e);
|
|
67
|
+
errored = true;
|
|
68
|
+
}
|
|
69
|
+
sending = false;
|
|
70
|
+
|
|
71
|
+
setTimeout(() => {
|
|
72
|
+
errored = false;
|
|
73
|
+
successfullySent = false;
|
|
74
|
+
}, 15000);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
let disabled = $derived(errored || successfullySent);
|
|
78
|
+
</script>
|
|
79
|
+
|
|
80
|
+
<div class="wrapper">
|
|
81
|
+
{#if explainer}
|
|
82
|
+
<div class="explainer">{@html translateFunc ? translateFunc(explainer) : ''}</div>
|
|
83
|
+
{/if}
|
|
84
|
+
<form onsubmit={submitMessage}>
|
|
85
|
+
<input type="hidden" value={userID} />
|
|
86
|
+
<label class:disabled>
|
|
87
|
+
{@html translateFunc ? translateFunc(nameLabel) : 'Name'}:
|
|
88
|
+
<TextInput type="text" marginForMessage={false} bind:value={name} enabled={!disabled} />
|
|
89
|
+
</label>
|
|
90
|
+
<label class:disabled>
|
|
91
|
+
{@html translateFunc ? translateFunc(emailLabel) : 'Email'}:
|
|
92
|
+
<TextInput type="email" marginForMessage={false} bind:value={email} enabled={!disabled} />
|
|
93
|
+
</label>
|
|
94
|
+
<label class="row-label"
|
|
95
|
+
><div class:disabled>
|
|
96
|
+
{@html translateFunc
|
|
97
|
+
? translateFunc(questionLabel)
|
|
98
|
+
: 'Your Message'}{#if showMaxCharsMessage}<span class="max-chars-message"
|
|
99
|
+
> ({currentCharsCount}/{maxCharsAllowed})</span
|
|
100
|
+
>{/if}:
|
|
101
|
+
</div>
|
|
102
|
+
|
|
103
|
+
<Notes {disabled} changed={questionChanged} />
|
|
104
|
+
</label>
|
|
105
|
+
{#if successfullySent}
|
|
106
|
+
<div class="success">
|
|
107
|
+
{translateFunc ? translateFunc(successfullySentText) : 'Successfully Sent Email'}
|
|
108
|
+
</div>
|
|
109
|
+
{/if}
|
|
110
|
+
{#if errored}
|
|
111
|
+
<div class="error">
|
|
112
|
+
{translateFunc ? translateFunc(sentErroredText) : 'Error Occurred Sending Email'}
|
|
113
|
+
</div>
|
|
114
|
+
{/if}
|
|
115
|
+
<div class="button-wrapper">
|
|
116
|
+
<Button
|
|
117
|
+
enabled={canSubmit && !disabled}
|
|
118
|
+
text={translateFunc ? translateFunc(submitText) : 'Submit'}
|
|
119
|
+
type="submit"
|
|
120
|
+
/>
|
|
121
|
+
</div>
|
|
122
|
+
</form>
|
|
123
|
+
{#if sending}
|
|
124
|
+
<Spinner />
|
|
125
|
+
{/if}
|
|
126
|
+
</div>
|
|
127
|
+
|
|
128
|
+
<style>
|
|
129
|
+
.wrapper {
|
|
130
|
+
background-color: var(--main-bg-color);
|
|
131
|
+
color: var(--main-font-color);
|
|
132
|
+
|
|
133
|
+
width: 100%;
|
|
134
|
+
display: flex;
|
|
135
|
+
|
|
136
|
+
padding: 1rem;
|
|
137
|
+
margin: 1rem;
|
|
138
|
+
:global(*) {
|
|
139
|
+
color: var(--main-font-color);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
form {
|
|
144
|
+
width: 100%;
|
|
145
|
+
display: flex;
|
|
146
|
+
flex-direction: column;
|
|
147
|
+
gap: 0.5rem;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
label {
|
|
151
|
+
display: flex;
|
|
152
|
+
gap: 1rem;
|
|
153
|
+
align-items: center;
|
|
154
|
+
justify-content: space-between;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.row-label {
|
|
158
|
+
flex-direction: column;
|
|
159
|
+
gap: 0.2rem;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.max-chars-message {
|
|
163
|
+
font-weight: bolder;
|
|
164
|
+
color: var(--alert-font-color);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.success {
|
|
168
|
+
color: var(--accept-font-color);
|
|
169
|
+
font-weight: bolder;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.error {
|
|
173
|
+
color: var(--alert-font-color);
|
|
174
|
+
font-weight: bolder;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.disabled {
|
|
178
|
+
color: var(--font-disabled-color);
|
|
179
|
+
}
|
|
180
|
+
</style>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ContactFormContent, I18nFacade } from './types.js';
|
|
2
|
+
type $$ComponentProps = ContactFormContent & I18nFacade;
|
|
3
|
+
declare const ContactForm: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
4
|
+
type ContactForm = ReturnType<typeof ContactForm>;
|
|
5
|
+
export default ContactForm;
|
package/dist/Photo.svelte.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PhotoContent, I18nFacade } from './types.js';
|
|
2
|
-
|
|
2
|
+
type $$ComponentProps = PhotoContent & I18nFacade;
|
|
3
|
+
declare const Photo: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
3
4
|
type Photo = ReturnType<typeof Photo>;
|
|
4
5
|
export default Photo;
|