accomadesc 0.4.8 → 0.4.10

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.
@@ -1,376 +0,0 @@
1
- <script lang="ts">
2
- import { DateTime, type DayNumbers, type MonthNumbers } from 'luxon';
3
- import {
4
- defaultMonthLabels,
5
- defaultWeekendLabel,
6
- OccupationState,
7
- occupationTypeFormatting,
8
- type OccupationType,
9
- type OccuplanTranslations,
10
- type DayHelper,
11
- type FirstMonth,
12
- realFirstMonth,
13
- contextKey,
14
- } from '../occuplan/state.svelte.js';
15
- import Button from '../basic/Button.svelte';
16
- import { browser } from '$app/environment';
17
- import Spinner from '../basic/Spinner.svelte';
18
- import { randomID } from '../names/gen.js';
19
- import { getContext, onMount, setContext, untrack } from 'svelte';
20
-
21
- let {
22
- url,
23
- debug = false,
24
- header = '',
25
- footer = '',
26
- weekendLabel = defaultWeekendLabel,
27
- monthLabels = defaultMonthLabels,
28
- numberOfMonth = 12,
29
- firstMonth = 1,
30
- maxWidth = '1200px',
31
- maxDate = DateTime.utc().plus({ years: 2 }),
32
- minDate = DateTime.utc(),
33
- typeLabels = {
34
- one: 'BOOKING',
35
- two: 'RESERVATION',
36
- three: 'PERSONAL',
37
- },
38
- }: OccuplanTranslations & {
39
- url: string;
40
- debug?: boolean;
41
- numberOfMonth?: number;
42
- firstMonth?: FirstMonth;
43
- minDate?: DateTime;
44
- maxDate?: DateTime;
45
- maxWidth?: string;
46
- } = $props();
47
-
48
- const id = randomID();
49
-
50
- const stateID = contextKey(untrack(() => url));
51
- let ss: OccupationState = getContext(stateID);
52
- if (!ss) {
53
- ss = new OccupationState(() => {
54
- return { iCalURL: url, debug };
55
- });
56
- setContext(stateID, ss);
57
- }
58
- let occupationState: OccupationState = $derived(ss);
59
-
60
- let page: number = $state(0);
61
- let rfMonth: number | DateTime = $derived(
62
- realFirstMonth(firstMonth, DateTime.utc().get('year'), numberOfMonth, page),
63
- );
64
-
65
- let currentMaxDate = $derived(rfMonth.plus({ month: numberOfMonth }));
66
-
67
- let months: DateTime[] = $derived.by(() => {
68
- const result = [];
69
- if (rfMonth.month == 1) {
70
- //result.push(rfMonth);
71
- }
72
-
73
- let fMonth: DateTime = DateTime.utc(rfMonth.year, rfMonth.month, 1);
74
- result.push(fMonth);
75
-
76
- let nMonth = fMonth.plus({ months: 1 });
77
- for (let c = 1; c < numberOfMonth; c++) {
78
- result.push(nMonth);
79
- nMonth = nMonth.plus({ months: 1 });
80
- }
81
- return result;
82
- });
83
-
84
- const nextClicked = () => {
85
- page += 1;
86
- };
87
-
88
- const prevClicked = () => {
89
- page -= 1;
90
- };
91
-
92
- const monthDays = [...Array(31).keys()].map((i) => i + 1);
93
- let days: DayHelper[] = $derived.by(() => {
94
- const ldays: DayHelper[] = [];
95
- if (!browser) return ldays;
96
- if (!occupationState || occupationState.loading) return ldays;
97
-
98
- for (const m of months) {
99
- for (let d: DayNumbers = 1; d <= 31; d++) {
100
- const day: DayHelper = {
101
- day: d,
102
- month: m.month as MonthNumbers,
103
- year: m.year,
104
- };
105
- ldays.push(day);
106
- }
107
- }
108
- return ldays;
109
- });
110
-
111
- let monthGridTemplateColumns = $derived(
112
- monthDays.reduce((s, d) => {
113
- s += ` [d${d}] 1fr`;
114
- return s;
115
- }, '[rowLegend] 1.5fr'),
116
- );
117
-
118
- let monthGridTemplateRows = $derived(
119
- months.reduce((s, m) => {
120
- if (m.month == 1 && s != '[columnLegend] 1fr [firstYearRow] 1fr') {
121
- s += ` [y${m.year}Row] 1fr`;
122
- }
123
-
124
- s += ` [m${m.month}y${m.year}] 1fr`;
125
- return s;
126
- }, '[columnLegend] 1fr [firstYearRow] 1fr'),
127
- );
128
-
129
- let foundOccupationTypes: OccupationType[] = $derived(
130
- occupationState
131
- ? occupationState.occupations.reduce((res, occupation) => {
132
- if (!res.includes(occupation.type)) {
133
- res.push(occupation.type);
134
- }
135
- return res;
136
- }, [] as OccupationType[])
137
- : [],
138
- );
139
-
140
- onMount(() => {
141
- occupationState.loadOccupations();
142
- });
143
- </script>
144
-
145
- {#if !occupationState || occupationState.loading}
146
- <Spinner />
147
- {/if}
148
-
149
- <section class="occuplan-wrapper" style="max-width: {maxWidth};">
150
- <header class="occupation-plan-header">
151
- <div class="header-controls">
152
- {#if rfMonth >= minDate}
153
- <Button text="<" clicked={prevClicked} />
154
- {/if}
155
- </div>
156
- <div class="header-label"><h3>{@html header}</h3></div>
157
- <div class="header-controls">
158
- {#if currentMaxDate <= maxDate}
159
- <Button text=">" clicked={nextClicked} />
160
- {/if}
161
- </div>
162
- </header>
163
- <main
164
- style="
165
- grid-template-columns: {monthGridTemplateColumns};
166
- grid-template-rows: {monthGridTemplateRows};
167
- "
168
- >
169
- <div
170
- class="corner"
171
- style="
172
- grid-area: columnLegend / rowLegend / columnLegend / rowLegend;
173
- background-color: var(--occuplan-main-bg-color);"
174
- >
175
- &nbsp;
176
- </div>
177
-
178
- {#each monthDays as d}
179
- <div class="monthday-header" style="grid-area: columnLegend / d{d} / columnLegend / d{d};">
180
- <span>{d}</span>
181
- </div>
182
- {/each}
183
-
184
- <div class="year-label" style="grid-area: firstYearRow / d1 / firstYearRow / d31;">
185
- <span>{rfMonth.year}</span>
186
- </div>
187
- {#each months as m, i (`${m.year}-${m.month}`)}
188
- {#if m.month == 1 && i != 0}
189
- <div class="year-label" style="grid-area: y{m.year}Row / d1 / y{m.year}Row / d31;">
190
- <span>{m.year}</span>
191
- </div>
192
- {/if}
193
- <div
194
- id={`${m.year}-${m.month}-${id}`}
195
- class="month-label"
196
- style="grid-area: m{m.month}y{m.year} / rowLegend / m{m.month}y{m.year} / rowLegend;"
197
- >
198
- <span>{monthLabels[m.month as MonthNumbers]}</span>
199
- </div>
200
- {/each}
201
-
202
- {#if occupationState}
203
- {#each days as d (`${d.year}-${d.month}-${d.day}`)}
204
- <div
205
- id={`${d.year}-${d.month}-${d.day}-${id}`}
206
- class="day"
207
- style="
208
- outline: var(--occuplan-grid-border);
209
- grid-area: m{d.month}y{d.year} / d{d.day} / m{d.month}y{d.year} / d{d.day};
210
- {occupationState.occupationStyle(d, true, maxDate)}
211
- "
212
- >
213
- &nbsp;
214
- </div>
215
- {/each}
216
- {/if}
217
- </main>
218
- <footer>
219
- <div class="legend">
220
- <span>{weekendLabel}</span>
221
- <div
222
- id="weekend-legend"
223
- class="legend-entry-marker"
224
- style="
225
- outline: var(--occuplan-grid-border);
226
- background: radial-gradient(var(--occuplan-weekend-bg-color), var(--occuplan-main-bg-color), var(--occuplan-main-bg-color));
227
- "
228
- >
229
- &nbsp;
230
- </div>
231
- {#each foundOccupationTypes as t}
232
- {@const format = occupationTypeFormatting(t)}
233
- <span>{typeLabels[t]}</span>
234
- <div
235
- id="occupation-type-{t}-legend"
236
- class="legend-entry-marker"
237
- style="background-color: {format.bgColor}; outline: var(--occuplan-grid-border);"
238
- >
239
- &nbsp;
240
- </div>
241
- {/each}
242
- </div>
243
- <div class="footer-content">
244
- {@html footer}
245
- </div>
246
- </footer>
247
- </section>
248
-
249
- <style>
250
- .footer-content {
251
- display: flex;
252
- flex-direction: column;
253
- justify-content: flex-end;
254
- }
255
-
256
- .legend {
257
- display: grid;
258
- grid-template-columns: [label] 1fr [marker] 1rem;
259
- column-gap: 1rem;
260
- text-transform: capitalize;
261
- font-variant: small-caps;
262
-
263
- span {
264
- color: var(--occuplan-main-font-color);
265
- }
266
- }
267
-
268
- .legend-entry-marker {
269
- width: 1rem;
270
- height: 1rem;
271
- }
272
-
273
- main {
274
- display: grid;
275
- width: 100%;
276
- overflow-x: auto;
277
- }
278
-
279
- .month-label {
280
- aspect-ratio: 3 / 2;
281
- display: flex;
282
- align-items: center;
283
- border-bottom: var(--occuplan-grid-border);
284
- border-top: var(--occuplan-grid-border);
285
- color: var(--occuplan-months-font-color);
286
- background-color: var(--occuplan-months-bg-color);
287
- container-type: size;
288
- container-name: month-label;
289
- padding-left: 0.3rem;
290
- height: 100%;
291
-
292
- span {
293
- font-size: clamp(0.9rem, 55cqh, 2rem);
294
- color: var(--occuplan-months-font-color);
295
- }
296
- }
297
-
298
- .monthday-header {
299
- text-align: center;
300
- aspect-ratio: 1;
301
- display: inline-grid;
302
- align-content: center;
303
- outline: var(--occuplan-grid-border);
304
- background-color: var(--occuplan-days-header-bg-color);
305
- color: var(--occuplan-days-header-font-color);
306
- container-type: size;
307
- container-name: month-header;
308
-
309
- span {
310
- color: var(--occuplan-days-header-font-color);
311
- font-size: clamp(0.9rem, 55cqh, 2rem);
312
- }
313
- }
314
-
315
- .occupation-plan-header {
316
- display: flex;
317
- flex-direction: row;
318
- width: 100%;
319
- justify-content: space-between;
320
- margin-bottom: 0.5rem;
321
- }
322
-
323
- .header-label {
324
- text-transform: capitalize;
325
- font-variant: small-caps;
326
- font-weight: bold;
327
-
328
- h3 {
329
- padding-top: 0;
330
- padding-bottom: 0.2rem;
331
- color: var(--occuplan-main-font-color);
332
- }
333
- }
334
-
335
- .header-controls {
336
- width: 2rem;
337
- }
338
-
339
- .occuplan-wrapper {
340
- height: 100%;
341
- width: calc(100% - 0.5rem);
342
- padding: 0.5rem;
343
- margin: 0;
344
- display: flex;
345
- flex-direction: column;
346
- flex-wrap: nowrap;
347
- align-items: center;
348
-
349
- border: var(--occuplan-main-border);
350
- color: var(--occuplan-main-font-color);
351
- background-color: var(--occuplan-main-bg-color);
352
- }
353
-
354
- footer {
355
- display: flex;
356
- flex-direction: row;
357
- align-items: stretch;
358
- justify-content: space-between;
359
- width: 100%;
360
- margin-top: 1rem;
361
- }
362
-
363
- .year-label {
364
- display: flex;
365
- justify-content: center;
366
- align-items: center;
367
- container-type: size;
368
- container-name: year-label;
369
- text-decoration: underline;
370
- height: 100%;
371
- span {
372
- color: var(--occuplan-main-font-color);
373
- font-size: clamp(1rem, 55cqh, 2rem);
374
- }
375
- }
376
- </style>
@@ -1,120 +0,0 @@
1
- <script lang="ts">
2
- import OccuPlanGrid from '../occuplan/OccuPlanGrid.svelte';
3
- import OccuPlanRows from '../occuplan/OccuPlanRows.svelte';
4
- import {
5
- type OccuplanTranslations,
6
- type OccuplanMiscProps,
7
- defaultWeekendLabel,
8
- defaultMonthLabels,
9
- defaultWeekdayLabels,
10
- defaultMonthHeaderFormat,
11
- contextKey,
12
- OccupationState,
13
- } from '../occuplan/state.svelte.js';
14
- import { DateTime } from 'luxon';
15
- import { getContext, setContext, untrack } from 'svelte';
16
-
17
- let {
18
- url,
19
- header = '',
20
- footer = '',
21
- debug = false,
22
- weekendLabel = defaultWeekendLabel,
23
- monthLabels = defaultMonthLabels,
24
- weekdayLabels = defaultWeekdayLabels,
25
- monthHeaderFormat = defaultMonthHeaderFormat,
26
- gridNumberOfMonths = 8,
27
- gridFirstMonth = '-1',
28
- gridMaxWidth = '1200px',
29
- rowsNumberOfMonths = 12,
30
- rowsFirstMonth = 1,
31
- rowsMaxWidth = '1200px',
32
- toggleGridOffset = 640,
33
- toggleRowsOffset = 640,
34
- maxDate = DateTime.utc().plus({ years: 2 }),
35
- minDate = DateTime.utc(),
36
- nextPage = '>',
37
- prevPage = '<',
38
- typeLabels = {
39
- one: 'BOOKING',
40
- two: 'RESERVATION',
41
- three: 'PERSONAL',
42
- },
43
- }: OccuplanTranslations & OccuplanMiscProps = $props();
44
-
45
- /*
46
- use different component based on different media size.
47
- */
48
- let w: number = $state(0);
49
- let showGrid: boolean = $state(false);
50
- let showRows: boolean = $state(true);
51
-
52
- $effect(() => {
53
- if (w < toggleGridOffset && showRows) {
54
- showGrid = true;
55
- showRows = false;
56
- }
57
- });
58
- $effect(() => {
59
- if (w > toggleRowsOffset && showGrid) {
60
- showRows = true;
61
- showGrid = false;
62
- }
63
- });
64
-
65
- const stateID = contextKey(untrack(() => url));
66
- let ss: OccupationState = getContext(stateID);
67
- if (!ss) {
68
- ss = new OccupationState(() => {
69
- return { iCalURL: url, debug };
70
- });
71
- setContext(stateID, ss);
72
- }
73
- </script>
74
-
75
- <div class="calendar-wrapper" bind:clientWidth={w}>
76
- {#if showRows}
77
- <OccuPlanRows
78
- {debug}
79
- {url}
80
- {header}
81
- {footer}
82
- {weekendLabel}
83
- {monthLabels}
84
- {maxDate}
85
- {minDate}
86
- maxWidth={rowsMaxWidth}
87
- numberOfMonth={rowsNumberOfMonths}
88
- firstMonth={rowsFirstMonth}
89
- {typeLabels}
90
- />
91
- {:else if showGrid}
92
- <OccuPlanGrid
93
- {debug}
94
- {url}
95
- {header}
96
- {footer}
97
- {nextPage}
98
- {prevPage}
99
- {weekdayLabels}
100
- {monthLabels}
101
- {maxDate}
102
- {minDate}
103
- maxWidth={gridMaxWidth}
104
- {monthHeaderFormat}
105
- numberOfMonth={gridNumberOfMonths}
106
- firstMonth={gridFirstMonth}
107
- {typeLabels}
108
- />
109
- {/if}
110
- </div>
111
-
112
- <style>
113
- .calendar-wrapper {
114
- display: flex;
115
- justify-content: center;
116
- min-width: 210px;
117
- max-width: 110rem;
118
- width: 100%;
119
- }
120
- </style>
@@ -1,157 +0,0 @@
1
- export const DefaultCalTranslations = {
2
- es: {
3
- weekdayLabels: {
4
- 1: 'Lu',
5
- 2: 'Ma',
6
- 3: 'Mi',
7
- 4: 'Ju',
8
- 5: 'Vi',
9
- 6: 'Sa',
10
- 7: 'Do',
11
- },
12
- monthLabels: {
13
- 1: 'Ene',
14
- 2: 'Feb',
15
- 3: 'Mar',
16
- 4: 'Abr',
17
- 5: 'May',
18
- 6: 'Jun',
19
- 7: 'Jul',
20
- 8: 'Ago',
21
- 9: 'Sep',
22
- 10: 'Oct',
23
- 11: 'Nov',
24
- 12: 'Dic',
25
- },
26
- weekendLabel: 'Fin de Semana',
27
- typeLabels: {
28
- one: 'Ocupado',
29
- two: 'Ocupade',
30
- three: '',
31
- },
32
- },
33
- fr: {
34
- weekdayLabels: {
35
- 1: 'Lu',
36
- 2: 'Ma',
37
- 3: 'Me',
38
- 4: 'Je',
39
- 5: 'Ve',
40
- 6: 'Sa',
41
- 7: 'Di',
42
- },
43
- monthLabels: {
44
- 1: 'Jan',
45
- 2: 'Fév',
46
- 3: 'Mar',
47
- 4: 'Avr',
48
- 5: 'Mai',
49
- 6: 'Juin',
50
- 7: 'Juil',
51
- 8: 'Août',
52
- 9: 'Sept',
53
- 10: 'Oct',
54
- 11: 'Nov',
55
- 12: 'Déc',
56
- },
57
- weekendLabel: 'Week-end',
58
- typeLabels: {
59
- one: 'Occupé',
60
- two: 'Occupé',
61
- three: '',
62
- },
63
- },
64
- pl: {
65
- weekdayLabels: {
66
- 1: 'Pon',
67
- 2: 'Wt',
68
- 3: 'Śr',
69
- 4: 'Czw',
70
- 5: 'Pt',
71
- 6: 'Sob',
72
- 7: 'Ndz',
73
- },
74
- monthLabels: {
75
- 1: 'Sty',
76
- 2: 'Lut',
77
- 3: 'Mar',
78
- 4: 'Kwi',
79
- 5: 'Maj',
80
- 6: 'Cze',
81
- 7: 'Lip',
82
- 8: 'Sie',
83
- 9: 'Wrz',
84
- 10: 'Paź',
85
- 11: 'Lis',
86
- 12: 'Gru',
87
- },
88
- weekendLabel: 'Weekend',
89
- typeLabels: {
90
- one: 'Zajęty',
91
- two: 'Zajęty',
92
- three: '',
93
- },
94
- },
95
- en: {
96
- weekdayLabels: {
97
- 1: 'Mo',
98
- 2: 'Tu',
99
- 3: 'We',
100
- 4: 'Th',
101
- 5: 'Fr',
102
- 6: 'Sa',
103
- 7: 'Su',
104
- },
105
- monthLabels: {
106
- 1: 'Jan',
107
- 2: 'Feb',
108
- 3: 'Mar',
109
- 4: 'Apr',
110
- 5: 'May',
111
- 6: 'Jun',
112
- 7: 'Jul',
113
- 8: 'Aug',
114
- 9: 'Sep',
115
- 10: 'Oct',
116
- 11: 'Nov',
117
- 12: 'Dec',
118
- },
119
- weekendLabel: 'Weekend',
120
- typeLabels: {
121
- one: 'Occupied',
122
- two: 'Blocked',
123
- three: 'Requested',
124
- },
125
- },
126
- de: {
127
- weekdayLabels: {
128
- 1: 'Mo',
129
- 2: 'Di',
130
- 3: 'Mi',
131
- 4: 'Do',
132
- 5: 'Fr',
133
- 6: 'Sa',
134
- 7: 'So',
135
- },
136
- monthLabels: {
137
- 1: 'Jan',
138
- 2: 'Feb',
139
- 3: 'Mär',
140
- 4: 'Apr',
141
- 5: 'Mai',
142
- 6: 'Jun',
143
- 7: 'Jul',
144
- 8: 'Aug',
145
- 9: 'Sep',
146
- 10: 'Okt',
147
- 11: 'Nov',
148
- 12: 'Dez',
149
- },
150
- weekendLabel: 'Wochenende',
151
- typeLabels: {
152
- one: 'Belegt',
153
- two: 'Geblockt',
154
- three: 'Anfrage',
155
- },
156
- },
157
- };