@careflair/common 1.0.4 → 1.0.6

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.
Files changed (47) hide show
  1. package/dist/constants/index.d.ts +78 -0
  2. package/dist/constants/index.js +102 -13
  3. package/dist/index.d.ts +8 -7
  4. package/dist/index.js +23 -19
  5. package/dist/interfaces/common-fields.input.d.ts +15 -15
  6. package/dist/interfaces/common-fields.input.js +2 -2
  7. package/dist/interfaces/common-fields.output.d.ts +26 -26
  8. package/dist/interfaces/common-fields.output.js +2 -2
  9. package/dist/interfaces/index.d.ts +0 -0
  10. package/dist/interfaces/index.js +1 -0
  11. package/dist/schemas/availabilitySchemaValidation.d.ts +56 -56
  12. package/dist/schemas/availabilitySchemaValidation.js +79 -79
  13. package/dist/schemas/businessServicesValidation.d.ts +6 -6
  14. package/dist/schemas/businessServicesValidation.js +23 -23
  15. package/dist/schemas/educationSchemas.d.ts +38 -38
  16. package/dist/schemas/educationSchemas.js +29 -29
  17. package/dist/schemas/forms.d.ts +210 -0
  18. package/dist/schemas/forms.js +192 -0
  19. package/dist/schemas/hourlyRateSchemaValidation.d.ts +36 -36
  20. package/dist/schemas/hourlyRateSchemaValidation.js +25 -25
  21. package/dist/schemas/index.d.ts +2 -6
  22. package/dist/schemas/index.js +18 -16
  23. package/dist/schemas/userValiationSchema.d.ts +30 -30
  24. package/dist/schemas/userValiationSchema.js +38 -38
  25. package/dist/schemas/validation.d.ts +33 -0
  26. package/dist/schemas/validation.js +38 -0
  27. package/dist/schemas/workHistorySchema.d.ts +33 -33
  28. package/dist/schemas/workHistorySchema.js +28 -28
  29. package/dist/utils/date.d.ts +35 -0
  30. package/dist/utils/date.js +166 -0
  31. package/dist/utils/debounce.d.ts +8 -0
  32. package/dist/utils/debounce.js +22 -0
  33. package/dist/utils/enum.d.ts +6 -0
  34. package/dist/utils/enum.js +9 -0
  35. package/dist/utils/index.d.ts +6 -0
  36. package/dist/utils/index.js +28 -0
  37. package/dist/utils/phone.d.ts +9 -0
  38. package/dist/utils/phone.js +52 -0
  39. package/dist/utils/time.d.ts +63 -0
  40. package/dist/utils/time.js +134 -0
  41. package/dist/utils/utils.d.ts +6 -6
  42. package/dist/utils/utils.js +9 -9
  43. package/dist/utils/video.d.ts +25 -0
  44. package/dist/utils/video.js +80 -0
  45. package/dist/utils/videoValidation.d.ts +31 -31
  46. package/dist/utils/videoValidation.js +119 -119
  47. package/package.json +81 -46
@@ -1,28 +1,28 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WorkHistorySchema = void 0;
4
- const zod_1 = require("zod");
5
- const limits_1 = require("../constants/limits");
6
- exports.WorkHistorySchema = zod_1.z
7
- .object({
8
- jobTitle: zod_1.z
9
- .string()
10
- .min(1, "Job title is required")
11
- .max(limits_1.WORK_HISTORY_TITLE_MAX_LENGTH, `Job title must be at most ${limits_1.WORK_HISTORY_TITLE_MAX_LENGTH} characters long`),
12
- startDate: zod_1.z.date(),
13
- endDate: zod_1.z.date().optional().nullable(),
14
- organisation: zod_1.z
15
- .string()
16
- .min(1, "Organisation is required")
17
- .max(limits_1.WORK_HISTORY_ORGANIZATION_MAX_LENGTH, `Organisation must be at most ${limits_1.WORK_HISTORY_ORGANIZATION_MAX_LENGTH} characters long`),
18
- isCurrentlyWorking: zod_1.z.boolean().default(false),
19
- })
20
- .refine((data) => {
21
- if (data.endDate) {
22
- return !data.isCurrentlyWorking;
23
- }
24
- return data.isCurrentlyWorking || data.endDate !== undefined;
25
- }, {
26
- message: "If there is an endDate, is Currently Working must be false. If is Currently Working is false, endDate must be provided.",
27
- path: ["endDate", "isCurrentlyWorking"],
28
- });
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WorkHistorySchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const limits_1 = require("../constants/limits");
6
+ exports.WorkHistorySchema = zod_1.z
7
+ .object({
8
+ jobTitle: zod_1.z
9
+ .string()
10
+ .min(1, "Job title is required")
11
+ .max(limits_1.WORK_HISTORY_TITLE_MAX_LENGTH, `Job title must be at most ${limits_1.WORK_HISTORY_TITLE_MAX_LENGTH} characters long`),
12
+ startDate: zod_1.z.date(),
13
+ endDate: zod_1.z.date().optional().nullable(),
14
+ organisation: zod_1.z
15
+ .string()
16
+ .min(1, "Organisation is required")
17
+ .max(limits_1.WORK_HISTORY_ORGANIZATION_MAX_LENGTH, `Organisation must be at most ${limits_1.WORK_HISTORY_ORGANIZATION_MAX_LENGTH} characters long`),
18
+ isCurrentlyWorking: zod_1.z.boolean().default(false),
19
+ })
20
+ .refine((data) => {
21
+ if (data.endDate) {
22
+ return !data.isCurrentlyWorking;
23
+ }
24
+ return data.isCurrentlyWorking || data.endDate !== undefined;
25
+ }, {
26
+ message: "If there is an endDate, is Currently Working must be false. If is Currently Working is false, endDate must be provided.",
27
+ path: ["endDate", "isCurrentlyWorking"],
28
+ });
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Format a date to display relative time (e.g., "2 hours ago", "Yesterday")
3
+ */
4
+ export declare const formatPostDate: (createdAt: Date) => string;
5
+ /**
6
+ * Format time difference between two dates (e.g., "2h ago", "3d ago")
7
+ */
8
+ export declare const formatTimeDifference: (startDate: Date, endDate?: Date) => string;
9
+ /**
10
+ * Formats date like WhatsApp:
11
+ * - For today: shows time (e.g., "2:30 PM")
12
+ * - For yesterday: shows "Yesterday"
13
+ * - For this week: shows day name (e.g., "Monday", "Tuesday")
14
+ * - For same year: shows day and month (e.g., "24 Jan")
15
+ * - For different year: shows day, month, and year (e.g., "24 Jan 2022")
16
+ */
17
+ export declare const formatWhatsAppStyle: (date: Date | string) => string;
18
+ /**
19
+ * Format job posting date consistently across the application
20
+ * Handles timezone conversion from UTC to user's local timezone
21
+ */
22
+ export declare const formatJobPostDate: (createdAt: string | Date) => string;
23
+ /**
24
+ * Format job posting date for absolute display (e.g., "Dec 15")
25
+ * Handles timezone conversion from UTC to user's local timezone
26
+ */
27
+ export declare const formatJobPostDateAbsolute: (createdAt: string | Date) => string;
28
+ /**
29
+ * Format a date/time to display in a user-friendly format
30
+ */
31
+ export declare const formatDateTime: (dateTime: string | Date) => string;
32
+ /**
33
+ * Format a date to display in a user-friendly format
34
+ */
35
+ export declare const formatDate: (dateTime: string | Date) => string;
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatDate = exports.formatDateTime = exports.formatJobPostDateAbsolute = exports.formatJobPostDate = exports.formatWhatsAppStyle = exports.formatTimeDifference = exports.formatPostDate = void 0;
4
+ const date_fns_1 = require("date-fns");
5
+ /**
6
+ * Format a date to display relative time (e.g., "2 hours ago", "Yesterday")
7
+ */
8
+ const formatPostDate = (createdAt) => {
9
+ const now = new Date();
10
+ const minutesAgo = (0, date_fns_1.differenceInMinutes)(now, createdAt);
11
+ const hoursAgo = (0, date_fns_1.differenceInHours)(now, createdAt);
12
+ const daysAgo = (0, date_fns_1.differenceInDays)(now, createdAt);
13
+ if (minutesAgo < 1) {
14
+ return "Just now";
15
+ }
16
+ if (minutesAgo < 60) {
17
+ return `${minutesAgo} minute${minutesAgo > 1 ? "s" : ""} ago`;
18
+ }
19
+ if (hoursAgo < 24) {
20
+ return `${hoursAgo} hour${hoursAgo > 1 ? "s" : ""} ago`;
21
+ }
22
+ if (daysAgo === 1) {
23
+ return "Yesterday";
24
+ }
25
+ if (daysAgo <= 7) {
26
+ return `${daysAgo} day${daysAgo > 1 ? "s" : ""} ago`;
27
+ }
28
+ // For older posts, show a formatted date
29
+ return (0, date_fns_1.format)(createdAt, "MMMM d, yyyy h:mm a"); // For example: "January 15, 2023 2:45 PM"
30
+ };
31
+ exports.formatPostDate = formatPostDate;
32
+ /**
33
+ * Format time difference between two dates (e.g., "2h ago", "3d ago")
34
+ */
35
+ const formatTimeDifference = (startDate, endDate = new Date()) => {
36
+ const duration = (0, date_fns_1.intervalToDuration)({ start: startDate, end: endDate });
37
+ const minutesDifference = (0, date_fns_1.differenceInMinutes)(endDate, startDate);
38
+ // Return "just now" if less than 2 minutes
39
+ if (minutesDifference < 2) {
40
+ return "just now";
41
+ }
42
+ if (duration.years && duration.years >= 1) {
43
+ return `${duration.years}y ago`;
44
+ }
45
+ if (duration.weeks && duration.weeks >= 1) {
46
+ return `${duration.weeks}w ago`;
47
+ }
48
+ if (duration.days && duration.days >= 1) {
49
+ return `${duration.days}d ago`;
50
+ }
51
+ if (duration.hours && duration.hours >= 1) {
52
+ return `${duration.hours}h ago`;
53
+ }
54
+ if (duration.minutes && duration.minutes >= 1) {
55
+ return `${duration.minutes}m ago`;
56
+ }
57
+ return "just now"; // fallback if less than 1 minute
58
+ };
59
+ exports.formatTimeDifference = formatTimeDifference;
60
+ /**
61
+ * Formats date like WhatsApp:
62
+ * - For today: shows time (e.g., "2:30 PM")
63
+ * - For yesterday: shows "Yesterday"
64
+ * - For this week: shows day name (e.g., "Monday", "Tuesday")
65
+ * - For same year: shows day and month (e.g., "24 Jan")
66
+ * - For different year: shows day, month, and year (e.g., "24 Jan 2022")
67
+ */
68
+ const formatWhatsAppStyle = (date) => {
69
+ if (!date)
70
+ return "";
71
+ const messageDate = typeof date === "string" ? new Date(date) : date;
72
+ const now = new Date();
73
+ // Invalid date
74
+ if (isNaN(messageDate.getTime()))
75
+ return "";
76
+ // Today: show time (e.g., "2:30 PM")
77
+ if ((0, date_fns_1.isToday)(messageDate)) {
78
+ return (0, date_fns_1.format)(messageDate, "h:mm a");
79
+ }
80
+ // Yesterday: show "Yesterday"
81
+ if ((0, date_fns_1.isYesterday)(messageDate)) {
82
+ return "Yesterday";
83
+ }
84
+ // This week (but not today or yesterday): show day name (e.g., "Monday")
85
+ if ((0, date_fns_1.isSameWeek)(messageDate, now)) {
86
+ return (0, date_fns_1.format)(messageDate, "EEEE"); // Full day name
87
+ }
88
+ // Same year: show date without year (e.g., "24 Jan")
89
+ if ((0, date_fns_1.isSameYear)(messageDate, now)) {
90
+ return (0, date_fns_1.format)(messageDate, "d MMM");
91
+ }
92
+ // Different year: show date with year (e.g., "24 Jan 2022")
93
+ return (0, date_fns_1.format)(messageDate, "d MMM yyyy");
94
+ };
95
+ exports.formatWhatsAppStyle = formatWhatsAppStyle;
96
+ /**
97
+ * Format job posting date consistently across the application
98
+ * Handles timezone conversion from UTC to user's local timezone
99
+ */
100
+ const formatJobPostDate = (createdAt) => {
101
+ if (!createdAt)
102
+ return "";
103
+ const postDate = typeof createdAt === "string" ? new Date(createdAt) : createdAt;
104
+ const now = new Date();
105
+ // Invalid date
106
+ if (isNaN(postDate.getTime()))
107
+ return "";
108
+ const minutesAgo = (0, date_fns_1.differenceInMinutes)(now, postDate);
109
+ const hoursAgo = (0, date_fns_1.differenceInHours)(now, postDate);
110
+ const daysAgo = (0, date_fns_1.differenceInDays)(now, postDate);
111
+ if (minutesAgo < 1) {
112
+ return "Just now";
113
+ }
114
+ if (minutesAgo < 60) {
115
+ return `${minutesAgo} minute${minutesAgo > 1 ? "s" : ""} ago`;
116
+ }
117
+ if (hoursAgo < 24) {
118
+ return `${hoursAgo} hour${hoursAgo > 1 ? "s" : ""} ago`;
119
+ }
120
+ if (daysAgo === 1) {
121
+ return "Yesterday";
122
+ }
123
+ if (daysAgo <= 7) {
124
+ return `${daysAgo} day${daysAgo > 1 ? "s" : ""} ago`;
125
+ }
126
+ // For older posts, show formatted date in user's timezone
127
+ return (0, date_fns_1.format)(postDate, "MMM d");
128
+ };
129
+ exports.formatJobPostDate = formatJobPostDate;
130
+ /**
131
+ * Format job posting date for absolute display (e.g., "Dec 15")
132
+ * Handles timezone conversion from UTC to user's local timezone
133
+ */
134
+ const formatJobPostDateAbsolute = (createdAt) => {
135
+ if (!createdAt)
136
+ return "";
137
+ const postDate = typeof createdAt === "string" ? new Date(createdAt) : createdAt;
138
+ // Invalid date
139
+ if (isNaN(postDate.getTime()))
140
+ return "";
141
+ // Format date in user's local timezone
142
+ return (0, date_fns_1.format)(postDate, "MMM d");
143
+ };
144
+ exports.formatJobPostDateAbsolute = formatJobPostDateAbsolute;
145
+ /**
146
+ * Format a date/time to display in a user-friendly format
147
+ */
148
+ const formatDateTime = (dateTime) => {
149
+ return new Date(dateTime).toLocaleTimeString("en-US", {
150
+ hour: "numeric",
151
+ minute: "2-digit",
152
+ hour12: true,
153
+ });
154
+ };
155
+ exports.formatDateTime = formatDateTime;
156
+ /**
157
+ * Format a date to display in a user-friendly format
158
+ */
159
+ const formatDate = (dateTime) => {
160
+ return new Date(dateTime).toLocaleDateString("en-US", {
161
+ weekday: "long",
162
+ month: "short",
163
+ day: "numeric",
164
+ });
165
+ };
166
+ exports.formatDate = formatDate;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Creates a debounced version of a function
3
+ * Platform-agnostic implementation that works in both browser and Node.js
4
+ * @param func - The function to debounce
5
+ * @param delay - The delay in milliseconds
6
+ * @returns A debounced function
7
+ */
8
+ export declare function debounce<T extends (...args: any[]) => void>(func: T, delay: number): (...args: Parameters<T>) => void;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.debounce = debounce;
4
+ /**
5
+ * Creates a debounced version of a function
6
+ * Platform-agnostic implementation that works in both browser and Node.js
7
+ * @param func - The function to debounce
8
+ * @param delay - The delay in milliseconds
9
+ * @returns A debounced function
10
+ */
11
+ function debounce(func, delay) {
12
+ let timer;
13
+ return (...args) => {
14
+ if (timer !== undefined) {
15
+ clearTimeout(timer);
16
+ }
17
+ timer = setTimeout(() => {
18
+ func(...args);
19
+ timer = undefined;
20
+ }, delay);
21
+ };
22
+ }
@@ -0,0 +1,6 @@
1
+ type Option = {
2
+ label: string;
3
+ value: string;
4
+ };
5
+ export declare function enumToOptions<T extends Record<string, string>>(enumObj: T): Option[];
6
+ export {};
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.enumToOptions = enumToOptions;
4
+ function enumToOptions(enumObj) {
5
+ return Object.values(enumObj).map((value) => ({
6
+ label: value, // Use the enum value for the label
7
+ value: value, // Use the enum value for the value
8
+ }));
9
+ }
@@ -0,0 +1,6 @@
1
+ export * from "./phone";
2
+ export * from "./date";
3
+ export * from "./time";
4
+ export * from "./debounce";
5
+ export * from "./enum";
6
+ export * from "./video";
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ // Phone validation utilities
18
+ __exportStar(require("./phone"), exports);
19
+ // Date formatting utilities
20
+ __exportStar(require("./date"), exports);
21
+ // Time/shift utilities
22
+ __exportStar(require("./time"), exports);
23
+ // Functional utilities
24
+ __exportStar(require("./debounce"), exports);
25
+ // Enum utilities
26
+ __exportStar(require("./enum"), exports);
27
+ // Video validation utilities
28
+ __exportStar(require("./video"), exports);
@@ -0,0 +1,9 @@
1
+ export type PhoneValidationResult = {
2
+ isValid: boolean;
3
+ error?: string;
4
+ formattedNumber?: string;
5
+ };
6
+ /**
7
+ * Validates an Australian phone number (mobile only)
8
+ */
9
+ export declare function validateAustralianPhoneNumber(phoneNumber: string): PhoneValidationResult;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateAustralianPhoneNumber = validateAustralianPhoneNumber;
4
+ const libphonenumber_js_1 = require("libphonenumber-js");
5
+ /**
6
+ * Validates an Australian phone number (mobile only)
7
+ */
8
+ function validateAustralianPhoneNumber(phoneNumber) {
9
+ try {
10
+ // Trim whitespace
11
+ const trimmedNumber = phoneNumber.trim();
12
+ // Check if empty
13
+ if (!trimmedNumber) {
14
+ return {
15
+ isValid: false,
16
+ error: "Phone number cannot be empty",
17
+ };
18
+ }
19
+ // Check if it's a valid Australian mobile number
20
+ if (!(0, libphonenumber_js_1.isValidPhoneNumber)(trimmedNumber, "AU")) {
21
+ return {
22
+ isValid: false,
23
+ error: "Please enter a valid Australian phone number",
24
+ };
25
+ }
26
+ const parsedNumber = (0, libphonenumber_js_1.parsePhoneNumberFromString)(trimmedNumber, "AU");
27
+ if (!parsedNumber || parsedNumber.country !== "AU") {
28
+ return {
29
+ isValid: false,
30
+ error: "Please enter a valid Australian phone number",
31
+ };
32
+ }
33
+ // Check if it's a mobile number (landlines not allowed)
34
+ const numberType = parsedNumber.getType();
35
+ if (numberType !== "MOBILE" && numberType !== "FIXED_LINE_OR_MOBILE") {
36
+ return {
37
+ isValid: false,
38
+ error: "Only Australian mobile numbers are allowed",
39
+ };
40
+ }
41
+ // Just return valid - no formatting needed
42
+ return {
43
+ isValid: true,
44
+ };
45
+ }
46
+ catch {
47
+ return {
48
+ isValid: false,
49
+ error: "Please enter a valid Australian phone number",
50
+ };
51
+ }
52
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Parse time string to minutes for comparison
3
+ */
4
+ export declare const parseTimeToMinutes: (timeStr: string) => number;
5
+ /**
6
+ * Get shift duration in minutes
7
+ */
8
+ export declare const getShiftDurationMinutes: (startTime: string, endTime: string) => number;
9
+ /**
10
+ * Get shift duration in hours
11
+ */
12
+ export declare const getShiftDurationHours: (startTime: string, endTime: string) => number;
13
+ /**
14
+ * Check if two shifts overlap
15
+ */
16
+ export declare const areShiftsOverlapping: (shift1: {
17
+ startTime: string;
18
+ endTime: string;
19
+ }, shift2: {
20
+ startTime: string;
21
+ endTime: string;
22
+ }) => boolean;
23
+ /**
24
+ * Check if shifts overlap for a given day
25
+ */
26
+ export declare const checkForOverlappingShifts: (shifts: {
27
+ startTime: string;
28
+ endTime: string;
29
+ }[]) => boolean;
30
+ /**
31
+ * Check if a shift is too short (less than minimum minutes)
32
+ */
33
+ export declare const isShiftTooShort: (shift: {
34
+ startTime: string;
35
+ endTime: string;
36
+ }, minimumMinutes?: number) => boolean;
37
+ /**
38
+ * Validate a single shift
39
+ */
40
+ export declare const validateShift: (shift: {
41
+ startTime: string;
42
+ endTime: string;
43
+ }, allShifts: {
44
+ startTime: string;
45
+ endTime: string;
46
+ }[], shiftIndex: number) => {
47
+ errors: string[];
48
+ warnings: string[];
49
+ };
50
+ /**
51
+ * Generate a new shift time based on the last shift
52
+ */
53
+ export declare const generateNewShiftTime: (lastShift?: {
54
+ startTime: string;
55
+ endTime: string;
56
+ }) => {
57
+ startTime: string;
58
+ endTime: string;
59
+ };
60
+ /**
61
+ * Convert time string to ISO format
62
+ */
63
+ export declare const timeStringToISO: (timeString: string) => string;
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.timeStringToISO = exports.generateNewShiftTime = exports.validateShift = exports.isShiftTooShort = exports.checkForOverlappingShifts = exports.areShiftsOverlapping = exports.getShiftDurationHours = exports.getShiftDurationMinutes = exports.parseTimeToMinutes = void 0;
4
+ const date_fns_1 = require("date-fns");
5
+ /**
6
+ * Parse time string to minutes for comparison
7
+ */
8
+ const parseTimeToMinutes = (timeStr) => {
9
+ const [hours, minutes] = timeStr.split(":").map(Number);
10
+ return hours * 60 + minutes;
11
+ };
12
+ exports.parseTimeToMinutes = parseTimeToMinutes;
13
+ /**
14
+ * Get shift duration in minutes
15
+ */
16
+ const getShiftDurationMinutes = (startTime, endTime) => {
17
+ return (0, exports.parseTimeToMinutes)(endTime) - (0, exports.parseTimeToMinutes)(startTime);
18
+ };
19
+ exports.getShiftDurationMinutes = getShiftDurationMinutes;
20
+ /**
21
+ * Get shift duration in hours
22
+ */
23
+ const getShiftDurationHours = (startTime, endTime) => {
24
+ return (0, exports.getShiftDurationMinutes)(startTime, endTime) / 60;
25
+ };
26
+ exports.getShiftDurationHours = getShiftDurationHours;
27
+ /**
28
+ * Check if two shifts overlap
29
+ */
30
+ const areShiftsOverlapping = (shift1, shift2) => {
31
+ const start1 = (0, exports.parseTimeToMinutes)(shift1.startTime);
32
+ const end1 = (0, exports.parseTimeToMinutes)(shift1.endTime);
33
+ const start2 = (0, exports.parseTimeToMinutes)(shift2.startTime);
34
+ const end2 = (0, exports.parseTimeToMinutes)(shift2.endTime);
35
+ return start1 < end2 && start2 < end1;
36
+ };
37
+ exports.areShiftsOverlapping = areShiftsOverlapping;
38
+ /**
39
+ * Check if shifts overlap for a given day
40
+ */
41
+ const checkForOverlappingShifts = (shifts) => {
42
+ if (shifts.length <= 1)
43
+ return false;
44
+ // Sort shifts by start time
45
+ const sortedShifts = [...shifts].sort((a, b) => {
46
+ return (new Date(`2023-01-01T${a.startTime}`).getTime() -
47
+ new Date(`2023-01-01T${b.startTime}`).getTime());
48
+ });
49
+ // Check for overlaps
50
+ for (let i = 0; i < sortedShifts.length - 1; i++) {
51
+ const currentShiftEnd = new Date(`2023-01-01T${sortedShifts[i].endTime}`);
52
+ const nextShiftStart = new Date(`2023-01-01T${sortedShifts[i + 1].startTime}`);
53
+ if (currentShiftEnd > nextShiftStart) {
54
+ return true; // Found an overlap
55
+ }
56
+ }
57
+ return false;
58
+ };
59
+ exports.checkForOverlappingShifts = checkForOverlappingShifts;
60
+ /**
61
+ * Check if a shift is too short (less than minimum minutes)
62
+ */
63
+ const isShiftTooShort = (shift, minimumMinutes = 60) => {
64
+ const startTime = new Date(`2023-01-01T${shift.startTime}`);
65
+ const endTime = new Date(`2023-01-01T${shift.endTime}`);
66
+ // Calculate difference in minutes
67
+ const diffMinutes = (endTime.getTime() - startTime.getTime()) / (1000 * 60);
68
+ return diffMinutes < minimumMinutes;
69
+ };
70
+ exports.isShiftTooShort = isShiftTooShort;
71
+ /**
72
+ * Validate a single shift
73
+ */
74
+ const validateShift = (shift, allShifts, shiftIndex) => {
75
+ const errors = [];
76
+ const warnings = [];
77
+ // 1. Check if times are provided
78
+ if (!shift.startTime || !shift.endTime) {
79
+ errors.push("Both start and end times are required");
80
+ return { errors, warnings };
81
+ }
82
+ // 2. End time after start time
83
+ if ((0, exports.parseTimeToMinutes)(shift.endTime) <= (0, exports.parseTimeToMinutes)(shift.startTime)) {
84
+ errors.push("End time must be after start time");
85
+ }
86
+ else {
87
+ // 3. Minimum shift duration (1 hour)
88
+ const durationHours = (0, exports.getShiftDurationHours)(shift.startTime, shift.endTime);
89
+ if (durationHours < 1) {
90
+ errors.push("Shift must be at least 1 hour");
91
+ }
92
+ // 4. Maximum shift duration (12 hours)
93
+ if (durationHours > 12) {
94
+ errors.push("Shift must be at most 12 hours");
95
+ }
96
+ }
97
+ // 5. Check for overlapping shifts
98
+ const otherShifts = [...allShifts];
99
+ otherShifts.splice(shiftIndex, 1); // Remove current shift from array
100
+ for (let i = 0; i < otherShifts.length; i++) {
101
+ if ((0, exports.areShiftsOverlapping)(shift, otherShifts[i])) {
102
+ errors.push("Shifts cannot overlap");
103
+ break;
104
+ }
105
+ }
106
+ return { errors, warnings };
107
+ };
108
+ exports.validateShift = validateShift;
109
+ /**
110
+ * Generate a new shift time based on the last shift
111
+ */
112
+ const generateNewShiftTime = (lastShift) => {
113
+ let newStartTime = "09:00";
114
+ let newEndTime = "10:00";
115
+ if (lastShift) {
116
+ // Start the new shift right after the last shift ends (no gap)
117
+ const lastEndTime = new Date(`2023-01-01T${lastShift.endTime}`);
118
+ // Format the new start time
119
+ newStartTime = (0, date_fns_1.format)(lastEndTime, "HH:mm");
120
+ // Set end time 1 hour after start time
121
+ const newEnd = new Date(lastEndTime);
122
+ newEnd.setHours(newEnd.getHours() + 1);
123
+ newEndTime = (0, date_fns_1.format)(newEnd, "HH:mm");
124
+ }
125
+ return { startTime: newStartTime, endTime: newEndTime };
126
+ };
127
+ exports.generateNewShiftTime = generateNewShiftTime;
128
+ /**
129
+ * Convert time string to ISO format
130
+ */
131
+ const timeStringToISO = (timeString) => {
132
+ return new Date(`2023-01-01T${timeString}`).toISOString();
133
+ };
134
+ exports.timeStringToISO = timeStringToISO;
@@ -1,6 +1,6 @@
1
- type Option = {
2
- label: string;
3
- value: string;
4
- };
5
- export declare function enumToOptions<T extends Record<string, string>>(enumObj: T): Option[];
6
- export {};
1
+ type Option = {
2
+ label: string;
3
+ value: string;
4
+ };
5
+ export declare function enumToOptions<T extends Record<string, string>>(enumObj: T): Option[];
6
+ export {};
@@ -1,9 +1,9 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.enumToOptions = enumToOptions;
4
- function enumToOptions(enumObj) {
5
- return Object.values(enumObj).map((value) => ({
6
- label: value, // Use the enum value for the label
7
- value: value, // Use the enum value for the value
8
- }));
9
- }
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.enumToOptions = enumToOptions;
4
+ function enumToOptions(enumObj) {
5
+ return Object.values(enumObj).map((value) => ({
6
+ label: value, // Use the enum value for the label
7
+ value: value, // Use the enum value for the value
8
+ }));
9
+ }
@@ -0,0 +1,25 @@
1
+ export type VideoProvider = "youtube" | "vimeo" | "loom" | "tiktok";
2
+ export interface VideoValidationResult {
3
+ isValid: boolean;
4
+ provider?: VideoProvider;
5
+ error?: string;
6
+ }
7
+ /**
8
+ * Unified video link validation function
9
+ * @param url - The video URL to validate
10
+ * @param allowedProviders - Array of allowed video providers
11
+ * @returns VideoValidationResult object
12
+ */
13
+ export declare function validateVideoLink(url: string, allowedProviders: VideoProvider[]): VideoValidationResult;
14
+ /**
15
+ * Detect video provider from URL
16
+ */
17
+ export declare function detectVideoProvider(url: string): VideoProvider | null;
18
+ /**
19
+ * Check if URL is valid YouTube or Vimeo URL
20
+ */
21
+ export declare function isValidYouTubeOrVimeoUrl(url: string): boolean;
22
+ /**
23
+ * Check if URL is valid community video URL (YouTube, Vimeo, Loom, TikTok)
24
+ */
25
+ export declare function isValidCommunityVideoUrl(url: string): boolean;