@rkosafo/cai.components 0.0.68 → 0.0.70

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.
@@ -2,7 +2,6 @@
2
2
  import { onMount } from 'svelte';
3
3
  import { fade } from 'svelte/transition';
4
4
  import clsx from 'clsx';
5
- // import { Button, ToolbarButton, type DatepickerProps } from '../..';
6
5
  import { datepicker } from './index.js';
7
6
  import {
8
7
  parse,
@@ -50,7 +49,9 @@
50
49
  monthBtn = 'text-gray-700 dark:text-gray-300',
51
50
  class: className,
52
51
  elementRef = $bindable(),
53
- name
52
+ name,
53
+ // New placement prop
54
+ placement = 'bottom-start'
54
55
  }: DatepickerProps = $props();
55
56
 
56
57
  const theme = getTheme('datepicker');
@@ -450,7 +451,7 @@
450
451
  nav,
451
452
  dayButton,
452
453
  monthButton
453
- } = datepicker();
454
+ } = datepicker({ placement });
454
455
  </script>
455
456
 
456
457
  {#snippet navButton(forward: boolean)}
@@ -1,5 +1,5 @@
1
- import type { Classes } from "../../themes/themeUtils.js";
2
- import { type VariantProps } from "tailwind-variants";
1
+ import type { Classes } from '../../themes/themeUtils.js';
2
+ import { type VariantProps } from 'tailwind-variants';
3
3
  export type DatepickerVariants = VariantProps<typeof datepicker> & Classes<typeof datepicker>;
4
4
  export declare const datepicker: import("tailwind-variants").TVReturnType<{
5
5
  color: {
@@ -100,6 +100,47 @@ export declare const datepicker: import("tailwind-variants").TVReturnType<{
100
100
  false: {
101
101
  base: string;
102
102
  };
103
+ true: {
104
+ base: string;
105
+ };
106
+ };
107
+ placement: {
108
+ 'top-start': {
109
+ base: string;
110
+ };
111
+ top: {
112
+ base: string;
113
+ };
114
+ 'top-end': {
115
+ base: string;
116
+ };
117
+ 'bottom-start': {
118
+ base: string;
119
+ };
120
+ bottom: {
121
+ base: string;
122
+ };
123
+ 'bottom-end': {
124
+ base: string;
125
+ };
126
+ 'left-start': {
127
+ base: string;
128
+ };
129
+ left: {
130
+ base: string;
131
+ };
132
+ 'left-end': {
133
+ base: string;
134
+ };
135
+ 'right-start': {
136
+ base: string;
137
+ };
138
+ right: {
139
+ base: string;
140
+ };
141
+ 'right-end': {
142
+ base: string;
143
+ };
103
144
  };
104
145
  current: {
105
146
  true: {
@@ -227,6 +268,47 @@ export declare const datepicker: import("tailwind-variants").TVReturnType<{
227
268
  false: {
228
269
  base: string;
229
270
  };
271
+ true: {
272
+ base: string;
273
+ };
274
+ };
275
+ placement: {
276
+ 'top-start': {
277
+ base: string;
278
+ };
279
+ top: {
280
+ base: string;
281
+ };
282
+ 'top-end': {
283
+ base: string;
284
+ };
285
+ 'bottom-start': {
286
+ base: string;
287
+ };
288
+ bottom: {
289
+ base: string;
290
+ };
291
+ 'bottom-end': {
292
+ base: string;
293
+ };
294
+ 'left-start': {
295
+ base: string;
296
+ };
297
+ left: {
298
+ base: string;
299
+ };
300
+ 'left-end': {
301
+ base: string;
302
+ };
303
+ 'right-start': {
304
+ base: string;
305
+ };
306
+ right: {
307
+ base: string;
308
+ };
309
+ 'right-end': {
310
+ base: string;
311
+ };
230
312
  };
231
313
  current: {
232
314
  true: {
@@ -354,6 +436,47 @@ export declare const datepicker: import("tailwind-variants").TVReturnType<{
354
436
  false: {
355
437
  base: string;
356
438
  };
439
+ true: {
440
+ base: string;
441
+ };
442
+ };
443
+ placement: {
444
+ 'top-start': {
445
+ base: string;
446
+ };
447
+ top: {
448
+ base: string;
449
+ };
450
+ 'top-end': {
451
+ base: string;
452
+ };
453
+ 'bottom-start': {
454
+ base: string;
455
+ };
456
+ bottom: {
457
+ base: string;
458
+ };
459
+ 'bottom-end': {
460
+ base: string;
461
+ };
462
+ 'left-start': {
463
+ base: string;
464
+ };
465
+ left: {
466
+ base: string;
467
+ };
468
+ 'left-end': {
469
+ base: string;
470
+ };
471
+ 'right-start': {
472
+ base: string;
473
+ };
474
+ right: {
475
+ base: string;
476
+ };
477
+ 'right-end': {
478
+ base: string;
479
+ };
357
480
  };
358
481
  current: {
359
482
  true: {
@@ -1,56 +1,143 @@
1
- import { tv } from "tailwind-variants";
1
+ import { tv } from 'tailwind-variants';
2
2
  export const datepicker = tv({
3
3
  slots: {
4
- base: "inline-block rounded-lg bg-white dark:bg-gray-700 shadow-lg p-4",
5
- input: "w-full border-gray-300 rounded-md border px-4 py-2 text-sm focus:ring-2 focus:outline-none outline-none dark:border-gray-600 dark:bg-gray-700 dark:text-white disabled:cursor-not-allowed disabled:opacity-50",
6
- titleVariant: "mb-2 text-lg font-semibold text-gray-900 dark:text-white",
7
- polite: "text-sm rounded-lg text-gray-900 dark:text-white bg-white dark:bg-gray-700 font-semibold py-2.5 px-5 hover:bg-gray-100 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-200",
8
- button: "absolute inset-y-0 right-0 flex items-center px-3 text-gray-500 focus:outline-hidden dark:text-gray-400",
9
- actionButtons: "mt-4 flex justify-between",
10
- columnHeader: "text-center text-sm font-medium text-gray-500 dark:text-gray-400",
11
- grid: "grid grid-cols-7 gap-1 w-64",
12
- nav: "mb-4 flex items-center justify-between",
13
- dayButton: "h-8 w-full block flex-1 leading-9 border-0 rounded-lg cursor-pointer text-center font-semibold text-sm day p-0",
14
- monthButton: "rounded-lg px-3 py-2 text-sm hover:bg-gray-100 focus:ring-2 focus:ring-blue-500 dark:hover:bg-gray-700"
4
+ base: 'inline-block rounded-lg bg-white dark:bg-gray-700 shadow-lg p-4',
5
+ input: 'w-full border-gray-300 rounded-md border px-4 py-2 text-sm focus:ring-2 focus:outline-none outline-none dark:border-gray-600 dark:bg-gray-700 dark:text-white disabled:cursor-not-allowed disabled:opacity-50',
6
+ titleVariant: 'mb-2 text-lg font-semibold text-gray-900 dark:text-white',
7
+ polite: 'text-sm rounded-lg text-gray-900 dark:text-white bg-white dark:bg-gray-700 font-semibold py-2.5 px-5 hover:bg-gray-100 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-200',
8
+ button: 'absolute inset-y-0 right-0 flex items-center px-3 text-gray-500 focus:outline-hidden dark:text-gray-400',
9
+ actionButtons: 'mt-4 flex justify-between',
10
+ columnHeader: 'text-center text-sm font-medium text-gray-500 dark:text-gray-400',
11
+ grid: 'grid grid-cols-7 gap-1 w-64',
12
+ nav: 'mb-4 flex items-center justify-between',
13
+ dayButton: 'h-8 w-full block flex-1 leading-9 border-0 rounded-lg cursor-pointer text-center font-semibold text-sm day p-0',
14
+ monthButton: 'rounded-lg px-3 py-2 text-sm hover:bg-gray-100 focus:ring-2 focus:ring-blue-500 dark:hover:bg-gray-700'
15
15
  },
16
16
  variants: {
17
17
  color: {
18
- primary: { input: "focus:ring-primary-500 dark:focus:ring-primary-400", dayButton: "bg-primary-100 dark:bg-primary-900" },
19
- blue: { input: "focus:ring-blue-500 dark:focus:ring-blue-400", dayButton: "bg-blue-100 dark:bg-blue-900" },
20
- red: { input: "focus:ring-red-500 dark:focus:ring-red-400", dayButton: "bg-red-100 dark:bg-red-900" },
21
- green: { input: "focus:ring-green-500 dark:focus:ring-green-400", dayButton: "bg-green-100 dark:bg-green-900" },
22
- yellow: { input: "focus:ring-yellow-500 dark:focus:ring-yellow-400", dayButton: "bg-yellow-100 dark:bg-yellow-900" },
23
- purple: { input: "focus:ring-purple-500 dark:focus:ring-purple-400", dayButton: "bg-purple-100 dark:bg-purple-900" },
24
- dark: { input: "focus:ring-gray-500 dark:focus:ring-gray-400", dayButton: "bg-gray-100 dark:bg-gray-900" },
25
- light: { input: "focus:ring-gray-500 dark:focus:ring-gray-400", dayButton: "bg-gray-100 dark:bg-gray-900" },
26
- alternative: { input: "focus:ring-alternative-500 dark:focus:ring-alternative-400", dayButton: "bg-alternative-100 dark:bg-alternative-900" },
27
- secondary: { input: "focus:ring-secondary-500 dark:focus:ring-secondary-400", dayButton: "bg-secondary-100 dark:bg-secondary-900" },
28
- gray: { input: "focus:ring-gray-500 dark:focus:ring-gray-400", dayButton: "bg-gray-100 dark:bg-gray-900" },
29
- orange: { input: "focus:ring-orange-500 dark:focus:ring-orange-400", dayButton: "bg-orange-100 dark:bg-orange-900" },
30
- amber: { input: "focus:ring-amber-500 dark:focus:ring-amber-400", dayButton: "bg-amber-100 dark:bg-amber-900" },
31
- lime: { input: "focus:ring-lime-500 dark:focus:ring-lime-400", dayButton: "bg-lime-100 dark:bg-lime-900" },
32
- emerald: { input: "focus:ring-emerald-500 dark:focus:ring-emerald-400", dayButton: "bg-emerald-100 dark:bg-emerald-900" },
33
- teal: { input: "focus:ring-teal-500 dark:focus:ring-teal-400", dayButton: "bg-teal-100 dark:bg-teal-900" },
34
- cyan: { input: "focus:ring-cyan-500 dark:focus:ring-cyan-400", dayButton: "bg-cyan-100 dark:bg-cyan-900" },
35
- sky: { input: "focus:ring-sky-500 dark:focus:ring-sky-400", dayButton: "bg-sky-100 dark:bg-sky-900" },
36
- indigo: { input: "focus:ring-indigo-500 dark:focus:ring-indigo-400", dayButton: "bg-indigo-100 dark:bg-indigo-900" },
37
- violet: { input: "focus:ring-violet-500 dark:focus:ring-violet-400", dayButton: "bg-violet-100 dark:bg-violet-900" },
38
- fuchsia: { input: "focus:ring-fuchsia-500 dark:focus:ring-fuchsia-400", dayButton: "bg-fuchsia-100 dark:bg-fuchsia-900" },
39
- pink: { input: "focus:ring-pink-500 dark:focus:ring-pink-400", dayButton: "bg-pink-100 dark:bg-pink-900" },
40
- rose: { input: "focus:ring-rose-500 dark:focus:ring-rose-400", dayButton: "bg-rose-100 dark:bg-rose-900" }
18
+ primary: {
19
+ input: 'focus:ring-primary-500 dark:focus:ring-primary-400',
20
+ dayButton: 'bg-primary-100 dark:bg-primary-900'
21
+ },
22
+ blue: {
23
+ input: 'focus:ring-blue-500 dark:focus:ring-blue-400',
24
+ dayButton: 'bg-blue-100 dark:bg-blue-900'
25
+ },
26
+ red: {
27
+ input: 'focus:ring-red-500 dark:focus:ring-red-400',
28
+ dayButton: 'bg-red-100 dark:bg-red-900'
29
+ },
30
+ green: {
31
+ input: 'focus:ring-green-500 dark:focus:ring-green-400',
32
+ dayButton: 'bg-green-100 dark:bg-green-900'
33
+ },
34
+ yellow: {
35
+ input: 'focus:ring-yellow-500 dark:focus:ring-yellow-400',
36
+ dayButton: 'bg-yellow-100 dark:bg-yellow-900'
37
+ },
38
+ purple: {
39
+ input: 'focus:ring-purple-500 dark:focus:ring-purple-400',
40
+ dayButton: 'bg-purple-100 dark:bg-purple-900'
41
+ },
42
+ dark: {
43
+ input: 'focus:ring-gray-500 dark:focus:ring-gray-400',
44
+ dayButton: 'bg-gray-100 dark:bg-gray-900'
45
+ },
46
+ light: {
47
+ input: 'focus:ring-gray-500 dark:focus:ring-gray-400',
48
+ dayButton: 'bg-gray-100 dark:bg-gray-900'
49
+ },
50
+ alternative: {
51
+ input: 'focus:ring-alternative-500 dark:focus:ring-alternative-400',
52
+ dayButton: 'bg-alternative-100 dark:bg-alternative-900'
53
+ },
54
+ secondary: {
55
+ input: 'focus:ring-secondary-500 dark:focus:ring-secondary-400',
56
+ dayButton: 'bg-secondary-100 dark:bg-secondary-900'
57
+ },
58
+ gray: {
59
+ input: 'focus:ring-gray-500 dark:focus:ring-gray-400',
60
+ dayButton: 'bg-gray-100 dark:bg-gray-900'
61
+ },
62
+ orange: {
63
+ input: 'focus:ring-orange-500 dark:focus:ring-orange-400',
64
+ dayButton: 'bg-orange-100 dark:bg-orange-900'
65
+ },
66
+ amber: {
67
+ input: 'focus:ring-amber-500 dark:focus:ring-amber-400',
68
+ dayButton: 'bg-amber-100 dark:bg-amber-900'
69
+ },
70
+ lime: {
71
+ input: 'focus:ring-lime-500 dark:focus:ring-lime-400',
72
+ dayButton: 'bg-lime-100 dark:bg-lime-900'
73
+ },
74
+ emerald: {
75
+ input: 'focus:ring-emerald-500 dark:focus:ring-emerald-400',
76
+ dayButton: 'bg-emerald-100 dark:bg-emerald-900'
77
+ },
78
+ teal: {
79
+ input: 'focus:ring-teal-500 dark:focus:ring-teal-400',
80
+ dayButton: 'bg-teal-100 dark:bg-teal-900'
81
+ },
82
+ cyan: {
83
+ input: 'focus:ring-cyan-500 dark:focus:ring-cyan-400',
84
+ dayButton: 'bg-cyan-100 dark:bg-cyan-900'
85
+ },
86
+ sky: {
87
+ input: 'focus:ring-sky-500 dark:focus:ring-sky-400',
88
+ dayButton: 'bg-sky-100 dark:bg-sky-900'
89
+ },
90
+ indigo: {
91
+ input: 'focus:ring-indigo-500 dark:focus:ring-indigo-400',
92
+ dayButton: 'bg-indigo-100 dark:bg-indigo-900'
93
+ },
94
+ violet: {
95
+ input: 'focus:ring-violet-500 dark:focus:ring-violet-400',
96
+ dayButton: 'bg-violet-100 dark:bg-violet-900'
97
+ },
98
+ fuchsia: {
99
+ input: 'focus:ring-fuchsia-500 dark:focus:ring-fuchsia-400',
100
+ dayButton: 'bg-fuchsia-100 dark:bg-fuchsia-900'
101
+ },
102
+ pink: {
103
+ input: 'focus:ring-pink-500 dark:focus:ring-pink-400',
104
+ dayButton: 'bg-pink-100 dark:bg-pink-900'
105
+ },
106
+ rose: {
107
+ input: 'focus:ring-rose-500 dark:focus:ring-rose-400',
108
+ dayButton: 'bg-rose-100 dark:bg-rose-900'
109
+ }
41
110
  },
42
111
  inline: {
43
- false: { base: "absolute z-10 mt-1" }
112
+ false: { base: 'absolute z-50 mt-1' },
113
+ true: { base: 'inline-block' }
114
+ },
115
+ placement: {
116
+ 'top-start': { base: 'bottom-full left-0 mb-1' },
117
+ top: { base: 'bottom-full left-1/2 transform -translate-x-1/2 mb-1' },
118
+ 'top-end': { base: 'bottom-full right-0 mb-1' },
119
+ 'bottom-start': { base: 'top-full left-0 mt-1' },
120
+ bottom: { base: 'top-full left-1/2 transform -translate-x-1/2 mt-1' },
121
+ 'bottom-end': { base: 'top-full right-0 mt-1' },
122
+ 'left-start': { base: 'right-full top-0 mr-1' },
123
+ left: { base: 'right-full top-1/2 transform -translate-y-1/2 mr-1' },
124
+ 'left-end': { base: 'right-full bottom-0 mr-1' },
125
+ 'right-start': { base: 'left-full top-0 ml-1' },
126
+ right: { base: 'left-full top-1/2 transform -translate-y-1/2 ml-1' },
127
+ 'right-end': { base: 'left-full bottom-0 ml-1' }
44
128
  },
45
129
  current: {
46
- true: { dayButton: "text-gray-400 dark:text-gray-500" }
130
+ true: { dayButton: 'text-gray-400 dark:text-gray-500' }
47
131
  },
48
132
  today: {
49
- true: { dayButton: "font-bold" }
133
+ true: { dayButton: 'font-bold' }
50
134
  },
51
135
  unavailable: {
52
- true: { dayButton: "opacity-50 cursor-not-allowed hover:bg-gray-100 dark:hover:bg-gray-700" }
136
+ true: { dayButton: 'opacity-50 cursor-not-allowed hover:bg-gray-100 dark:hover:bg-gray-700' }
53
137
  }
54
138
  },
55
- compoundVariants: []
139
+ defaultVariants: {
140
+ placement: 'bottom-start',
141
+ inline: false
142
+ }
56
143
  });
@@ -0,0 +1,10 @@
1
+ <script lang="ts">
2
+ interface Props {
3
+ content: any;
4
+ }
5
+ let { content }: Props = $props();
6
+ </script>
7
+
8
+ <div class="h-full w-full">
9
+ {@html content}
10
+ </div>
@@ -0,0 +1,6 @@
1
+ interface Props {
2
+ content: any;
3
+ }
4
+ declare const MailingContent: import("svelte").Component<Props, {}, "">;
5
+ type MailingContent = ReturnType<typeof MailingContent>;
6
+ export default MailingContent;
@@ -1,5 +1,55 @@
1
1
  <script lang="ts">
2
+ import { Avatar } from '../../ui/avatar/index.js';
3
+ import DropdownDivider from '../../ui/dropdown/DropdownDivider.svelte';
4
+ import { IconifyIcon } from '../../ui/icons/index.js';
2
5
  import type { MailingHeaderProps } from './types.js';
3
6
 
4
- let { data, replyType = $bindable(undefined) }: MailingHeaderProps = $props();
7
+ let { data, replyType = $bindable(undefined), showReplies }: MailingHeaderProps = $props();
5
8
  </script>
9
+
10
+ <div class=" w-full bg-white p-4">
11
+ <div class="flex h-full w-full flex-col">
12
+ <p class="text-xl font-light">{data?.subject}</p>
13
+ <DropdownDivider />
14
+ <div class="flex justify-between pt-3">
15
+ <div class="flex items-center gap-2">
16
+ <Avatar class="h-10 w-10 bg-blue-600 text-white">{data?.user?.initials}</Avatar>
17
+ <div>
18
+ <p class="text-sm">
19
+ {`${data?.user?.firstName} ${data?.user?.surname} - ${data?.user?.staffNumber}`}
20
+ </p>
21
+ <div class="flex items-center gap-1">
22
+ <p class="text-xs text-gray-500 antialiased">to {data?.to}</p>
23
+ <button class="grid place-content-center rounded-full p-1.5 hover:bg-gray-200">
24
+ <IconifyIcon icon="solar:alt-arrow-down-bold" style="font-size: 14px;" />
25
+ </button>
26
+ </div>
27
+ </div>
28
+ </div>
29
+ <div class="flex items-center gap-3" class:hidden={!showReplies}>
30
+ <button
31
+ class="flex items-center gap-1 rounded-lg border border-gray-300 px-2 py-1 text-sm text-gray-700 shadow transition duration-100 hover:bg-gray-200"
32
+ onclick={() => (replyType = 'reply')}
33
+ >
34
+ <IconifyIcon icon="bi:reply" style="font-size: 17px;" />
35
+ Reply
36
+ </button>
37
+ <button
38
+ class="flex items-center gap-1 rounded-lg border border-gray-300 px-2 py-1 text-sm text-gray-700 shadow transition duration-100 hover:bg-gray-200"
39
+ onclick={() => (replyType = 'reply-all')}
40
+ >
41
+ <IconifyIcon icon="ri:reply-all-line" style="font-size: 17px;" />
42
+ Reply all
43
+ </button>
44
+ <button
45
+ class="flex items-center gap-1 rounded-lg border border-gray-300 px-2 py-1 text-sm text-gray-700 shadow transition duration-100 hover:bg-gray-200"
46
+ onclick={() => (replyType = 'forward')}
47
+ >
48
+ <IconifyIcon icon="mdi:forward-outline" style="font-size: 17px;" />
49
+ Forward
50
+ </button>
51
+ </div>
52
+ </div>
53
+ <!-- <Divider morePadding={false} /> -->
54
+ </div>
55
+ </div>
@@ -61,43 +61,46 @@
61
61
  }}
62
62
  />
63
63
  <div class="my-1 flex w-full cursor-pointer items-center justify-between p-1">
64
- <div class="flex items-center">
65
- <div class="mr-4 flex items-center gap-1 space-x-1">
66
- <button
67
- onclick={(e) => {
68
- toggleFavorited?.(id);
69
- }}
70
- aria-label="Not starred"
71
- >
72
- <IconifyIcon
73
- style="font-size: 24px"
74
- icon={isStared ? 'mdi:star' : 'mdi:star-outline'}
75
- class="flex justify-center transition-colors {isStared
76
- ? 'text-yellow-500 hover:text-yellow-600'
77
- : 'text-gray-500 hover:text-gray-900'}"
78
- />
79
- </button>
80
- <button
81
- onclick={(e) => {
82
- toggelImportant?.(id);
83
- }}
84
- aria-label="Click to mark this email as important"
85
- >
86
- <IconifyIcon
87
- style="font-size: 18px"
88
- icon={isImportant ? 'ic:outline-bookmark' : 'solar:bookmark-broken'}
89
- class="flex justify-center transition-colors {isImportant
90
- ? 'text-yellow-500 hover:text-yellow-600'
91
- : 'text-gray-500 hover:text-gray-900'}"
92
- />
93
- </button>
64
+ <div class="flex w-full items-center">
65
+ <div class="flex">
66
+ <div class="mr-4 flex items-center gap-1 space-x-1">
67
+ <button
68
+ onclick={(e) => {
69
+ toggleFavorited?.(id);
70
+ }}
71
+ aria-label="Not starred"
72
+ >
73
+ <IconifyIcon
74
+ style="font-size: 24px"
75
+ icon={isStared ? 'mdi:star' : 'mdi:star-outline'}
76
+ class="flex justify-center transition-colors {isStared
77
+ ? 'text-yellow-500 hover:text-yellow-600'
78
+ : 'text-gray-500 hover:text-gray-900'}"
79
+ />
80
+ </button>
81
+ <button
82
+ onclick={(e) => {
83
+ toggelImportant?.(id);
84
+ }}
85
+ aria-label="Click to mark this email as important"
86
+ >
87
+ <IconifyIcon
88
+ style="font-size: 18px"
89
+ icon={isImportant ? 'ic:outline-bookmark' : 'solar:bookmark-broken'}
90
+ class="flex justify-center transition-colors {isImportant
91
+ ? 'text-yellow-500 hover:text-yellow-600'
92
+ : 'text-gray-500 hover:text-gray-900'}"
93
+ />
94
+ </button>
95
+ </div>
96
+ <span class="w-56 truncate pr-2" class:font-bold={!isRead}>{sender}</span>
97
+ <span class="w-64 truncate" class:font-bold={!isRead}>{subject}</span>
98
+ <span class="mx-1">-</span>
94
99
  </div>
95
- <span class="w-56 truncate pr-2" class:font-bold={!isRead}>{sender}</span>
96
- <span class="w-64 truncate" class:font-bold={!isRead}>{subject}</span>
97
- <span class="mx-1">-</span>
98
- <span class="w-96 truncate text-sm text-gray-600">{message}</span>
100
+
101
+ <p class=" truncate max-l xl:max-w-2xl 2xl:max-w-5xl text-sm text-gray-600">{message}</p>
99
102
  </div>
100
- <div class="flex w-32 items-center justify-end">
103
+ <div class="flex w-32 shrink-0 items-center justify-end">
101
104
  <span class="text-sm" class:font-bold={!isRead} class:text-gray-500={isRead}>
102
105
  {formatDate(date)}
103
106
  </span>
@@ -5,18 +5,28 @@
5
5
  import MailingHeader from './MailingHeader.svelte';
6
6
  import { onMount } from 'svelte';
7
7
  import toast from 'svelte-french-toast';
8
+ import { getInitials } from '../../index.js';
9
+ import MailingContent from './MailingContent.svelte';
8
10
 
9
- let { readMessage, recordId, updatePageInfo }: MailingMessageViewerProps = $props();
11
+ let {
12
+ readMessage,
13
+ recordId = $bindable(0),
14
+ updatePageInfo,
15
+ showReplies = true,
16
+ showHeader = true
17
+ }: MailingMessageViewerProps = $props();
10
18
 
11
19
  let busy = $state(true);
12
20
  let header = $state<MailingHeaderData>({} as MailingHeaderData);
13
21
  let inputType = $state<MailingReplyType | undefined>(undefined);
22
+ let content = $state('');
14
23
 
15
24
  onMount(async () => {
16
25
  try {
17
26
  const ret = await readMessage(recordId);
18
27
  if (!ret?.success) {
19
28
  toast.error(ret?.message);
29
+ recordId = 0;
20
30
  return;
21
31
  }
22
32
  updatePageInfo?.({
@@ -27,7 +37,18 @@
27
37
  hasPreviousPage: false
28
38
  });
29
39
 
30
- console.log({ ret });
40
+ const { data } = ret;
41
+ header = {
42
+ subject: data?.subject ?? '',
43
+ user: {
44
+ firstName: data?.user.firstName ?? '',
45
+ surname: data?.user.surname ?? '',
46
+ staffNumber: data?.user.staffNumber ?? '',
47
+ initials: `${getInitials(data?.user.firstName)}${getInitials(data?.user.surname)}`
48
+ },
49
+ to: data?.to ?? ''
50
+ };
51
+ content = data.message ?? '';
31
52
  } catch (error: any) {
32
53
  toast.error(error?.message || error);
33
54
  } finally {
@@ -41,23 +62,26 @@
41
62
  <PageLoader size={50} />
42
63
  {:else}
43
64
  <div class="flex h-full w-full flex-col gap-2" in:slide>
44
- <div class="h-28 px-4 pt-4">
45
- <MailingHeader bind:replyType={inputType} data={header} />
65
+ <div class:hidden={!showHeader}>
66
+ <MailingHeader bind:replyType={inputType} data={header} {showReplies} />
46
67
  </div>
47
- <!-- <div class="fex-grow h-full w-full rounded bg-gray-100">
48
- <div class="flex h-[71vh] w-full flex-col gap-4">
49
- <div
50
- class="scrollbar-thumb-blue scrollbar-thumb-rounded scrollbar-track-blue-lighter scrollbar-w-2 scrolling-touch h-full flex-grow overflow-y-auto p-2"
51
- >
52
- <ContentSection {content} />
68
+ <div class="fex-grow h-full w-full">
69
+ <div
70
+ class:h-[71vh]={inputType}
71
+ class:h-full={!inputType}
72
+ class="flex w-full flex-col gap-4"
73
+ >
74
+ <div class="custom-scrollbar h-full flex-grow overflow-y-auto bg-white p-4">
75
+ <MailingContent {content} />
53
76
  </div>
54
- <div class="h-modal p-4 pt-2" class:hidden={!Boolean(inputType)}>
77
+ <div class="h-modal p-4 pt-2" class:hidden={!Boolean(inputType) || !showReplies}>
55
78
  <div class=" rounded-md bg-white p-4">
56
- <Reply {inputType} />
79
+ Reply
80
+ <!-- <Reply {inputType} /> -->
57
81
  </div>
58
82
  </div>
59
83
  </div>
60
- </div> -->
84
+ </div>
61
85
  </div>
62
86
  {/if}
63
87
  </div>
@@ -1,4 +1,4 @@
1
1
  import type { MailingMessageViewerProps } from './index.js';
2
- declare const MailingMessageViewer: import("svelte").Component<MailingMessageViewerProps, {}, "">;
2
+ declare const MailingMessageViewer: import("svelte").Component<MailingMessageViewerProps, {}, "recordId">;
3
3
  type MailingMessageViewer = ReturnType<typeof MailingMessageViewer>;
4
4
  export default MailingMessageViewer;
@@ -9,7 +9,8 @@
9
9
  type MailingMessage,
10
10
  type MailMarkReadToggleType,
11
11
  type MailFavariteToggleType,
12
- type MailPageInfo
12
+ type MailPageInfo,
13
+ type MailingActiveBox
13
14
  } from './index.js';
14
15
  import MailingMessageCard from './MailingMessageCard.svelte';
15
16
  import { toast, type CrudResult, type TableFilter } from '../../index.js';
@@ -28,6 +29,7 @@
28
29
  showMarkReadButton = true,
29
30
  showFavoriteButton = true,
30
31
  showMarkAsSpamButton = true,
32
+ showReplies = true,
31
33
  readInbox = $bindable((skip?: number, take?: number, filter?: TableFilter<any>) => {
32
34
  return null;
33
35
  }),
@@ -57,9 +59,7 @@
57
59
  }
58
60
  }: MailingModuleProps = $props();
59
61
 
60
- type ActiveBox = 'inbox' | 'outbox';
61
-
62
- let activeBox = $state<ActiveBox>('inbox');
62
+ let activeBox = $state<MailingActiveBox>('inbox');
63
63
  let pageInfo = new PageInfo();
64
64
  let menutItems = $state([
65
65
  { icon: 'bx:bxs-inbox', title: 'Inbox', count: 3, path: '' },
@@ -313,7 +313,7 @@
313
313
  }
314
314
 
315
315
  function updatePageInfo(val: MailPageInfo) {
316
- console.log({ val });
316
+ // console.log({ val });
317
317
  pageInfo.totalItems = 1;
318
318
  pageInfo.setHasNextPage(val.hasNextPage);
319
319
  pageInfo.setHasPrevPage(val.hasPreviousPage);
@@ -351,7 +351,7 @@
351
351
  onMarkAsSpamClick={handleMarkAsSpam}
352
352
  onToggleMarkReadClick={handleMarkAsRead}
353
353
  onToggleFavoriteClick={handleMarkAsFavorite}
354
- onBackClick={() => {
354
+ onBackClick={async () => {
355
355
  messageSelected = 0;
356
356
  selectedMessages = [];
357
357
  }}
@@ -375,9 +375,11 @@
375
375
  <PageLoader size={50} />
376
376
  {:else if messageSelected}
377
377
  <MailingMessageViewer
378
- recordId={messageSelected}
378
+ bind:recordId={messageSelected}
379
379
  readMessage={readAMessage}
380
380
  {updatePageInfo}
381
+ {showReplies}
382
+ showHeader={activeBox === 'inbox'}
381
383
  />
382
384
  {:else if messages.length}
383
385
  <div class="custom-scrollbar h-full w-full overflow-auto" in:slide>
@@ -5,3 +5,4 @@ export { default as MailToolBar } from './MailToolBar.svelte';
5
5
  export { default as MailingModule } from './MailingModule.svelte';
6
6
  export { default as MailingHeader } from './MailingHeader.svelte';
7
7
  export { default as MailingMessageViewer } from './MailingMessageViewer.svelte';
8
+ export { default as MailingContent } from './MailingContent.svelte';
@@ -5,3 +5,4 @@ export { default as MailToolBar } from './MailToolBar.svelte';
5
5
  export { default as MailingModule } from './MailingModule.svelte';
6
6
  export { default as MailingHeader } from './MailingHeader.svelte';
7
7
  export { default as MailingMessageViewer } from './MailingMessageViewer.svelte';
8
+ export { default as MailingContent } from './MailingContent.svelte';
@@ -71,6 +71,7 @@ export interface MailingModuleProps {
71
71
  toggleFavourite?: (id: string | number) => Promise<CrudResult<any>> | CrudResult<any> | null;
72
72
  toggelImportant?: (id: string | number) => Promise<CrudResult<any>> | CrudResult<any> | null;
73
73
  readAMessage: (id: string | number) => Promise<CrudResult<any>> | CrudResult<any> | null;
74
+ showReplies?: boolean;
74
75
  }
75
76
  export interface MailingMessageCardChecked {
76
77
  id: number;
@@ -104,10 +105,13 @@ export interface MailingMessageCardProps extends MailingMessage {
104
105
  toggelImportant?: (id: number) => void;
105
106
  toggleFavorited?: (id: number) => void;
106
107
  }
108
+ export type MailingActiveBox = 'inbox' | 'outbox';
107
109
  export interface MailingMessageViewerProps {
108
110
  readMessage: (id: number) => Promise<CrudResult<MailingMessage>> | CrudResult<MailingMessage> | null;
109
111
  recordId: number;
110
112
  updatePageInfo?: (val: MailPageInfo) => void;
113
+ showReplies?: boolean;
114
+ showHeader?: boolean;
111
115
  }
112
116
  export interface MailingHeaderData {
113
117
  subject: string;
@@ -123,4 +127,5 @@ export type MailingReplyType = 'reply' | 'reply-all' | 'forward';
123
127
  export interface MailingHeaderProps {
124
128
  data: MailingHeaderData;
125
129
  replyType: MailingReplyType | undefined;
130
+ showReplies?: boolean;
126
131
  }
@@ -329,6 +329,7 @@ export interface DatepickerProps extends DatepickerVariants, Omit<HTMLAttributes
329
329
  translationLocale?: string;
330
330
  elementRef?: HTMLInputElement;
331
331
  name?: string | undefined | null;
332
+ placement?: 'top-start' | 'top' | 'top-end' | 'bottom-start' | 'bottom' | 'bottom-end' | 'left-start' | 'left' | 'left-end' | 'right-start' | 'right' | 'right-end';
332
333
  }
333
334
  export interface DrawerProps extends DrawerVariants, HTMLAttributes<HTMLDivElement> {
334
335
  hidden: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rkosafo/cai.components",
3
- "version": "0.0.68",
3
+ "version": "0.0.70",
4
4
  "files": [
5
5
  "dist",
6
6
  "!dist/**/*.test.*",