@kiosinc/commons-rn 0.5.0 → 0.6.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.
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getWeekDayString = exports.getTodayStatus = exports.formatPeriodTime = exports.formatBusinessHours = void 0;
7
+ var _i18next = require("i18next");
8
+ const getWeekDayString = day => {
9
+ const days = [(0, _i18next.t)('daysOfWeek.sunday'), (0, _i18next.t)('daysOfWeek.monday'), (0, _i18next.t)('daysOfWeek.tuesday'), (0, _i18next.t)('daysOfWeek.wednesday'), (0, _i18next.t)('daysOfWeek.thursday'), (0, _i18next.t)('daysOfWeek.friday'), (0, _i18next.t)('daysOfWeek.saturday')];
10
+ return days[day] ?? '';
11
+ };
12
+ exports.getWeekDayString = getWeekDayString;
13
+ const formatPeriodTime = time => {
14
+ if (!time) {
15
+ return '';
16
+ }
17
+ const hours = parseInt(time.substring(0, 2), 10);
18
+ const minutes = parseInt(time.substring(2), 10);
19
+
20
+ // No conversion, just format the raw time
21
+ const period = hours >= 12 ? 'pm' : 'am';
22
+ const formattedHours = hours % 12 || 12;
23
+ return `${formattedHours}:${minutes.toString().padStart(2, '0')}${period}`;
24
+ };
25
+ exports.formatPeriodTime = formatPeriodTime;
26
+ const getTodayStatus = (periods, utcOffset) => {
27
+ if (!periods || periods.length === 0) {
28
+ return {
29
+ main: (0, _i18next.t)('restaurant.closedToday'),
30
+ isOpen: false,
31
+ statusFlag: null
32
+ };
33
+ }
34
+ const now = new Date();
35
+ const localTime = new Date(now.getTime() + (utcOffset ?? 0) * 60000);
36
+ const today = localTime.getUTCDay(); // 0-6 (Sunday-Saturday)
37
+
38
+ // Sort periods by open time
39
+ const sortedPeriods = [...periods].sort((a, b) => Number(a.open.day) - Number(b.open.day));
40
+ let nextOpeningPeriod = null;
41
+ for (const period of sortedPeriods) {
42
+ const openDay = Number(period.open.day);
43
+ const closeDay = Number(period.close.day);
44
+ const openTime = period.open.time;
45
+ const closeTime = period.close.time;
46
+
47
+ // Create Date objects for open and close
48
+ const openDate = new Date(localTime);
49
+ const closeDate = new Date(localTime);
50
+
51
+ // Set open time
52
+ openDate.setUTCDate(localTime.getUTCDate() + (openDay - today + 7) % 7);
53
+ openDate.setUTCHours(Number(openTime.slice(0, 2)));
54
+ openDate.setUTCMinutes(Number(openTime.slice(2, 4)));
55
+
56
+ // Set close time
57
+ closeDate.setUTCDate(localTime.getUTCDate() + (closeDay - today + 7) % 7);
58
+ closeDate.setUTCHours(Number(closeTime.slice(0, 2)));
59
+ closeDate.setUTCMinutes(Number(closeTime.slice(2, 4)));
60
+ const isOpenNow = localTime >= openDate && localTime < closeDate;
61
+ if (isOpenNow) {
62
+ const minutesToClose = Math.floor((closeDate.getTime() - localTime.getTime()) / 60000);
63
+ const isClosingSoon = minutesToClose < 60;
64
+ return {
65
+ main: isClosingSoon ? (0, _i18next.t)('restaurant.closesSoon') : (0, _i18next.t)('restaurant.openNow'),
66
+ additional: `${(0, _i18next.t)('restaurant.closesAt')} ${formatPeriodTime(closeTime)}`,
67
+ isOpen: true,
68
+ statusFlag: isClosingSoon ? 'closingSoon' : null
69
+ };
70
+ }
71
+ const minutesToOpen = Math.floor((openDate.getTime() - localTime.getTime()) / 60000);
72
+ if (minutesToOpen > 0 && minutesToOpen <= 60) {
73
+ return {
74
+ main: (0, _i18next.t)('restaurant.openingSoon'),
75
+ additional: `${(0, _i18next.t)('restaurant.opensAt')} ${formatPeriodTime(openTime)}`,
76
+ isOpen: false,
77
+ statusFlag: 'openingSoon'
78
+ };
79
+ }
80
+
81
+ // Track next opening period if no match yet
82
+ if (!nextOpeningPeriod || openDate < new Date(localTime.getTime() + (Number(nextOpeningPeriod.open.day) - today + 7) % 7 * 86400000)) {
83
+ nextOpeningPeriod = period;
84
+ }
85
+ }
86
+ return {
87
+ main: (0, _i18next.t)('restaurant.closedNow'),
88
+ additional: nextOpeningPeriod ? `${(0, _i18next.t)('restaurant.opensAt')} ${getWeekDayString(nextOpeningPeriod.open.day)} ${formatPeriodTime(nextOpeningPeriod.open.time)}` : undefined,
89
+ isOpen: false,
90
+ statusFlag: null
91
+ };
92
+ };
93
+ exports.getTodayStatus = getTodayStatus;
94
+ const WEEK_DAYS = [0, 1, 2, 3, 4, 5, 6]; // Sunday = 0, Saturday = 6
95
+
96
+ const formatBusinessHours = periods => {
97
+ if (!periods || periods.length === 0) {
98
+ return WEEK_DAYS.map(dayNum => ({
99
+ day: getWeekDayString(dayNum),
100
+ time: 'Closed'
101
+ }));
102
+ }
103
+
104
+ // Group periods by day
105
+ const dayMap = {};
106
+ periods.forEach(({
107
+ open,
108
+ close
109
+ }) => {
110
+ const openTime = formatPeriodTime(open.time);
111
+ const closeTime = formatPeriodTime(close.time);
112
+ dayMap[open.day] = `${openTime} - ${closeTime}`;
113
+ });
114
+
115
+ // Build full week
116
+ return WEEK_DAYS.map(dayNum => ({
117
+ day: getWeekDayString(dayNum),
118
+ time: dayMap[dayNum] ?? 'Closed'
119
+ }));
120
+ };
121
+ exports.formatBusinessHours = formatBusinessHours;
122
+ //# sourceMappingURL=businessHours.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_i18next","require","getWeekDayString","day","days","t","exports","formatPeriodTime","time","hours","parseInt","substring","minutes","period","formattedHours","toString","padStart","getTodayStatus","periods","utcOffset","length","main","isOpen","statusFlag","now","Date","localTime","getTime","today","getUTCDay","sortedPeriods","sort","a","b","Number","open","nextOpeningPeriod","openDay","closeDay","close","openTime","closeTime","openDate","closeDate","setUTCDate","getUTCDate","setUTCHours","slice","setUTCMinutes","isOpenNow","minutesToClose","Math","floor","isClosingSoon","additional","minutesToOpen","undefined","WEEK_DAYS","formatBusinessHours","map","dayNum","dayMap","forEach"],"sourceRoot":"../../../src","sources":["helpers/businessHours.ts"],"mappings":"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"}
@@ -15,6 +15,31 @@ Object.defineProperty(exports, "NotificationHandler", {
15
15
  return _NotificationHandler.NotificationHandler;
16
16
  }
17
17
  });
18
+ Object.defineProperty(exports, "formatBusinessHours", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _businessHours.formatBusinessHours;
22
+ }
23
+ });
24
+ Object.defineProperty(exports, "formatPeriodTime", {
25
+ enumerable: true,
26
+ get: function () {
27
+ return _businessHours.formatPeriodTime;
28
+ }
29
+ });
30
+ Object.defineProperty(exports, "getTodayStatus", {
31
+ enumerable: true,
32
+ get: function () {
33
+ return _businessHours.getTodayStatus;
34
+ }
35
+ });
36
+ Object.defineProperty(exports, "getWeekDayString", {
37
+ enumerable: true,
38
+ get: function () {
39
+ return _businessHours.getWeekDayString;
40
+ }
41
+ });
18
42
  var _AssetManager = require("./AssetManager");
19
43
  var _NotificationHandler = require("./notifications/NotificationHandler");
44
+ var _businessHours = require("./businessHours");
20
45
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_AssetManager","require","_NotificationHandler"],"sourceRoot":"../../../src","sources":["helpers/index.ts"],"mappings":";;;;;;;;;;;;;;;;;AAAA,IAAAA,aAAA,GAAAC,OAAA;AACA,IAAAC,oBAAA,GAAAD,OAAA"}
1
+ {"version":3,"names":["_AssetManager","require","_NotificationHandler","_businessHours"],"sourceRoot":"../../../src","sources":["helpers/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,aAAA,GAAAC,OAAA;AACA,IAAAC,oBAAA,GAAAD,OAAA;AAEA,IAAAE,cAAA,GAAAF,OAAA"}
@@ -0,0 +1,112 @@
1
+ import { t } from 'i18next';
2
+ export const getWeekDayString = day => {
3
+ const days = [t('daysOfWeek.sunday'), t('daysOfWeek.monday'), t('daysOfWeek.tuesday'), t('daysOfWeek.wednesday'), t('daysOfWeek.thursday'), t('daysOfWeek.friday'), t('daysOfWeek.saturday')];
4
+ return days[day] ?? '';
5
+ };
6
+ export const formatPeriodTime = time => {
7
+ if (!time) {
8
+ return '';
9
+ }
10
+ const hours = parseInt(time.substring(0, 2), 10);
11
+ const minutes = parseInt(time.substring(2), 10);
12
+
13
+ // No conversion, just format the raw time
14
+ const period = hours >= 12 ? 'pm' : 'am';
15
+ const formattedHours = hours % 12 || 12;
16
+ return `${formattedHours}:${minutes.toString().padStart(2, '0')}${period}`;
17
+ };
18
+ export const getTodayStatus = (periods, utcOffset) => {
19
+ if (!periods || periods.length === 0) {
20
+ return {
21
+ main: t('restaurant.closedToday'),
22
+ isOpen: false,
23
+ statusFlag: null
24
+ };
25
+ }
26
+ const now = new Date();
27
+ const localTime = new Date(now.getTime() + (utcOffset ?? 0) * 60000);
28
+ const today = localTime.getUTCDay(); // 0-6 (Sunday-Saturday)
29
+
30
+ // Sort periods by open time
31
+ const sortedPeriods = [...periods].sort((a, b) => Number(a.open.day) - Number(b.open.day));
32
+ let nextOpeningPeriod = null;
33
+ for (const period of sortedPeriods) {
34
+ const openDay = Number(period.open.day);
35
+ const closeDay = Number(period.close.day);
36
+ const openTime = period.open.time;
37
+ const closeTime = period.close.time;
38
+
39
+ // Create Date objects for open and close
40
+ const openDate = new Date(localTime);
41
+ const closeDate = new Date(localTime);
42
+
43
+ // Set open time
44
+ openDate.setUTCDate(localTime.getUTCDate() + (openDay - today + 7) % 7);
45
+ openDate.setUTCHours(Number(openTime.slice(0, 2)));
46
+ openDate.setUTCMinutes(Number(openTime.slice(2, 4)));
47
+
48
+ // Set close time
49
+ closeDate.setUTCDate(localTime.getUTCDate() + (closeDay - today + 7) % 7);
50
+ closeDate.setUTCHours(Number(closeTime.slice(0, 2)));
51
+ closeDate.setUTCMinutes(Number(closeTime.slice(2, 4)));
52
+ const isOpenNow = localTime >= openDate && localTime < closeDate;
53
+ if (isOpenNow) {
54
+ const minutesToClose = Math.floor((closeDate.getTime() - localTime.getTime()) / 60000);
55
+ const isClosingSoon = minutesToClose < 60;
56
+ return {
57
+ main: isClosingSoon ? t('restaurant.closesSoon') : t('restaurant.openNow'),
58
+ additional: `${t('restaurant.closesAt')} ${formatPeriodTime(closeTime)}`,
59
+ isOpen: true,
60
+ statusFlag: isClosingSoon ? 'closingSoon' : null
61
+ };
62
+ }
63
+ const minutesToOpen = Math.floor((openDate.getTime() - localTime.getTime()) / 60000);
64
+ if (minutesToOpen > 0 && minutesToOpen <= 60) {
65
+ return {
66
+ main: t('restaurant.openingSoon'),
67
+ additional: `${t('restaurant.opensAt')} ${formatPeriodTime(openTime)}`,
68
+ isOpen: false,
69
+ statusFlag: 'openingSoon'
70
+ };
71
+ }
72
+
73
+ // Track next opening period if no match yet
74
+ if (!nextOpeningPeriod || openDate < new Date(localTime.getTime() + (Number(nextOpeningPeriod.open.day) - today + 7) % 7 * 86400000)) {
75
+ nextOpeningPeriod = period;
76
+ }
77
+ }
78
+ return {
79
+ main: t('restaurant.closedNow'),
80
+ additional: nextOpeningPeriod ? `${t('restaurant.opensAt')} ${getWeekDayString(nextOpeningPeriod.open.day)} ${formatPeriodTime(nextOpeningPeriod.open.time)}` : undefined,
81
+ isOpen: false,
82
+ statusFlag: null
83
+ };
84
+ };
85
+ const WEEK_DAYS = [0, 1, 2, 3, 4, 5, 6]; // Sunday = 0, Saturday = 6
86
+
87
+ export const formatBusinessHours = periods => {
88
+ if (!periods || periods.length === 0) {
89
+ return WEEK_DAYS.map(dayNum => ({
90
+ day: getWeekDayString(dayNum),
91
+ time: 'Closed'
92
+ }));
93
+ }
94
+
95
+ // Group periods by day
96
+ const dayMap = {};
97
+ periods.forEach(({
98
+ open,
99
+ close
100
+ }) => {
101
+ const openTime = formatPeriodTime(open.time);
102
+ const closeTime = formatPeriodTime(close.time);
103
+ dayMap[open.day] = `${openTime} - ${closeTime}`;
104
+ });
105
+
106
+ // Build full week
107
+ return WEEK_DAYS.map(dayNum => ({
108
+ day: getWeekDayString(dayNum),
109
+ time: dayMap[dayNum] ?? 'Closed'
110
+ }));
111
+ };
112
+ //# sourceMappingURL=businessHours.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["t","getWeekDayString","day","days","formatPeriodTime","time","hours","parseInt","substring","minutes","period","formattedHours","toString","padStart","getTodayStatus","periods","utcOffset","length","main","isOpen","statusFlag","now","Date","localTime","getTime","today","getUTCDay","sortedPeriods","sort","a","b","Number","open","nextOpeningPeriod","openDay","closeDay","close","openTime","closeTime","openDate","closeDate","setUTCDate","getUTCDate","setUTCHours","slice","setUTCMinutes","isOpenNow","minutesToClose","Math","floor","isClosingSoon","additional","minutesToOpen","undefined","WEEK_DAYS","formatBusinessHours","map","dayNum","dayMap","forEach"],"sourceRoot":"../../../src","sources":["helpers/businessHours.ts"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
1
  export { AssetManager } from './AssetManager';
2
2
  export { NotificationHandler } from './notifications/NotificationHandler';
3
+ export { getWeekDayString, formatPeriodTime, getTodayStatus, formatBusinessHours } from './businessHours';
3
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["AssetManager","NotificationHandler"],"sourceRoot":"../../../src","sources":["helpers/index.ts"],"mappings":"AAAA,SAASA,YAAY,QAAQ,gBAAgB;AAC7C,SAASC,mBAAmB,QAAQ,qCAAqC"}
1
+ {"version":3,"names":["AssetManager","NotificationHandler","getWeekDayString","formatPeriodTime","getTodayStatus","formatBusinessHours"],"sourceRoot":"../../../src","sources":["helpers/index.ts"],"mappings":"AAAA,SAASA,YAAY,QAAQ,gBAAgB;AAC7C,SAASC,mBAAmB,QAAQ,qCAAqC;AAEzE,SACEC,gBAAgB,EAChBC,gBAAgB,EAChBC,cAAc,EACdC,mBAAmB,QACd,iBAAiB"}
@@ -0,0 +1,17 @@
1
+ import type { Period } from '@kiosinc/commons-types';
2
+ export declare const getWeekDayString: (day: number) => string;
3
+ export declare const formatPeriodTime: (time: string) => string;
4
+ type TodayStatus = {
5
+ main: string;
6
+ additional?: string;
7
+ isOpen: boolean;
8
+ statusFlag?: 'closingSoon' | 'openingSoon' | null;
9
+ };
10
+ export declare const getTodayStatus: (periods: Period[] | null, utcOffset?: number) => TodayStatus;
11
+ type BusinessHoursEntry = {
12
+ day: string;
13
+ time: string;
14
+ };
15
+ export declare const formatBusinessHours: (periods: Period[] | null) => BusinessHoursEntry[];
16
+ export {};
17
+ //# sourceMappingURL=businessHours.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"businessHours.d.ts","sourceRoot":"","sources":["../../../../src/helpers/businessHours.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAGrD,eAAO,MAAM,gBAAgB,QAAS,MAAM,KAAG,MAW9C,CAAC;AAEF,eAAO,MAAM,gBAAgB,SAAU,MAAM,KAAG,MAY/C,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,aAAa,GAAG,aAAa,GAAG,IAAI,CAAC;CACnD,CAAC;AAEF,eAAO,MAAM,cAAc,YAChB,MAAM,EAAE,GAAG,IAAI,cACZ,MAAM,KACjB,WAkGF,CAAC;AAEF,KAAK,kBAAkB,GAAG;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAIF,eAAO,MAAM,mBAAmB,YACrB,MAAM,EAAE,GAAG,IAAI,KACvB,kBAAkB,EAqBpB,CAAC"}
@@ -1,3 +1,4 @@
1
1
  export { AssetManager } from './AssetManager';
2
2
  export { NotificationHandler } from './notifications/NotificationHandler';
3
+ export { getWeekDayString, formatPeriodTime, getTodayStatus, formatBusinessHours, } from './businessHours';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/helpers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/helpers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAE1E,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,mBAAmB,GACpB,MAAM,iBAAiB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kiosinc/commons-rn",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Common Code",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -194,7 +194,7 @@
194
194
  "dependencies": {
195
195
  "@gorhom/bottom-sheet": "^4.6.1",
196
196
  "@hookform/resolvers": "^3.3.2",
197
- "@kiosinc/commons-types": "^0.0.17",
197
+ "@kiosinc/commons-types": "^0.0.58",
198
198
  "@material/material-color-utilities": "^0.3.0",
199
199
  "@react-native-firebase/firestore": "^20.3.0",
200
200
  "@react-native-firebase/messaging": "^20.3.0",
@@ -0,0 +1,171 @@
1
+ import type { Period } from '@kiosinc/commons-types';
2
+ import { t } from 'i18next';
3
+
4
+ export const getWeekDayString = (day: number): string => {
5
+ const days = [
6
+ t('daysOfWeek.sunday'),
7
+ t('daysOfWeek.monday'),
8
+ t('daysOfWeek.tuesday'),
9
+ t('daysOfWeek.wednesday'),
10
+ t('daysOfWeek.thursday'),
11
+ t('daysOfWeek.friday'),
12
+ t('daysOfWeek.saturday'),
13
+ ];
14
+ return days[day] ?? '';
15
+ };
16
+
17
+ export const formatPeriodTime = (time: string): string => {
18
+ if (!time) {
19
+ return '';
20
+ }
21
+
22
+ const hours = parseInt(time.substring(0, 2), 10);
23
+ const minutes = parseInt(time.substring(2), 10);
24
+
25
+ // No conversion, just format the raw time
26
+ const period = hours >= 12 ? 'pm' : 'am';
27
+ const formattedHours = hours % 12 || 12;
28
+ return `${formattedHours}:${minutes.toString().padStart(2, '0')}${period}`;
29
+ };
30
+
31
+ type TodayStatus = {
32
+ main: string;
33
+ additional?: string;
34
+ isOpen: boolean;
35
+ statusFlag?: 'closingSoon' | 'openingSoon' | null;
36
+ };
37
+
38
+ export const getTodayStatus = (
39
+ periods: Period[] | null,
40
+ utcOffset?: number
41
+ ): TodayStatus => {
42
+ if (!periods || periods.length === 0) {
43
+ return {
44
+ main: t('restaurant.closedToday'),
45
+ isOpen: false,
46
+ statusFlag: null,
47
+ };
48
+ }
49
+
50
+ const now = new Date();
51
+ const localTime = new Date(now.getTime() + (utcOffset ?? 0) * 60000);
52
+
53
+ const today = localTime.getUTCDay(); // 0-6 (Sunday-Saturday)
54
+
55
+ // Sort periods by open time
56
+ const sortedPeriods = [...periods].sort(
57
+ (a, b) => Number(a.open.day) - Number(b.open.day)
58
+ );
59
+
60
+ let nextOpeningPeriod: Period | null = null;
61
+
62
+ for (const period of sortedPeriods) {
63
+ const openDay = Number(period.open.day);
64
+ const closeDay = Number(period.close.day);
65
+ const openTime = period.open.time;
66
+ const closeTime = period.close.time;
67
+
68
+ // Create Date objects for open and close
69
+ const openDate = new Date(localTime);
70
+ const closeDate = new Date(localTime);
71
+
72
+ // Set open time
73
+ openDate.setUTCDate(localTime.getUTCDate() + ((openDay - today + 7) % 7));
74
+ openDate.setUTCHours(Number(openTime.slice(0, 2)));
75
+ openDate.setUTCMinutes(Number(openTime.slice(2, 4)));
76
+
77
+ // Set close time
78
+ closeDate.setUTCDate(localTime.getUTCDate() + ((closeDay - today + 7) % 7));
79
+ closeDate.setUTCHours(Number(closeTime.slice(0, 2)));
80
+ closeDate.setUTCMinutes(Number(closeTime.slice(2, 4)));
81
+
82
+ const isOpenNow = localTime >= openDate && localTime < closeDate;
83
+
84
+ if (isOpenNow) {
85
+ const minutesToClose = Math.floor(
86
+ (closeDate.getTime() - localTime.getTime()) / 60000
87
+ );
88
+
89
+ const isClosingSoon = minutesToClose < 60;
90
+
91
+ return {
92
+ main: isClosingSoon
93
+ ? t('restaurant.closesSoon')
94
+ : t('restaurant.openNow'),
95
+ additional: `${t('restaurant.closesAt')} ${formatPeriodTime(
96
+ closeTime
97
+ )}`,
98
+ isOpen: true,
99
+ statusFlag: isClosingSoon ? 'closingSoon' : null,
100
+ };
101
+ }
102
+
103
+ const minutesToOpen = Math.floor(
104
+ (openDate.getTime() - localTime.getTime()) / 60000
105
+ );
106
+
107
+ if (minutesToOpen > 0 && minutesToOpen <= 60) {
108
+ return {
109
+ main: t('restaurant.openingSoon'),
110
+ additional: `${t('restaurant.opensAt')} ${formatPeriodTime(openTime)}`,
111
+ isOpen: false,
112
+ statusFlag: 'openingSoon',
113
+ };
114
+ }
115
+
116
+ // Track next opening period if no match yet
117
+ if (
118
+ !nextOpeningPeriod ||
119
+ openDate <
120
+ new Date(
121
+ localTime.getTime() +
122
+ ((Number(nextOpeningPeriod.open.day) - today + 7) % 7) * 86400000
123
+ )
124
+ ) {
125
+ nextOpeningPeriod = period;
126
+ }
127
+ }
128
+
129
+ return {
130
+ main: t('restaurant.closedNow'),
131
+ additional: nextOpeningPeriod
132
+ ? `${t('restaurant.opensAt')} ${getWeekDayString(
133
+ nextOpeningPeriod.open.day
134
+ )} ${formatPeriodTime(nextOpeningPeriod.open.time)}`
135
+ : undefined,
136
+ isOpen: false,
137
+ statusFlag: null,
138
+ };
139
+ };
140
+
141
+ type BusinessHoursEntry = {
142
+ day: string;
143
+ time: string;
144
+ };
145
+
146
+ const WEEK_DAYS = [0, 1, 2, 3, 4, 5, 6]; // Sunday = 0, Saturday = 6
147
+
148
+ export const formatBusinessHours = (
149
+ periods: Period[] | null
150
+ ): BusinessHoursEntry[] => {
151
+ if (!periods || periods.length === 0) {
152
+ return WEEK_DAYS.map((dayNum) => ({
153
+ day: getWeekDayString(dayNum),
154
+ time: 'Closed',
155
+ }));
156
+ }
157
+
158
+ // Group periods by day
159
+ const dayMap: Record<number, string> = {};
160
+ periods.forEach(({ open, close }) => {
161
+ const openTime = formatPeriodTime(open.time);
162
+ const closeTime = formatPeriodTime(close.time);
163
+ dayMap[open.day] = `${openTime} - ${closeTime}`;
164
+ });
165
+
166
+ // Build full week
167
+ return WEEK_DAYS.map((dayNum) => ({
168
+ day: getWeekDayString(dayNum),
169
+ time: dayMap[dayNum] ?? 'Closed',
170
+ }));
171
+ };
@@ -1,2 +1,9 @@
1
1
  export { AssetManager } from './AssetManager';
2
2
  export { NotificationHandler } from './notifications/NotificationHandler';
3
+
4
+ export {
5
+ getWeekDayString,
6
+ formatPeriodTime,
7
+ getTodayStatus,
8
+ formatBusinessHours,
9
+ } from './businessHours';