@feedmepos/mf-order-setting 0.0.53 → 0.0.56-dev.1

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 (40) hide show
  1. package/.tsbuildinfo +1 -0
  2. package/dist/{KioskDevicesView-CMKNjgWx.js → KioskDevicesView-CccsAZqK.js} +1 -1
  3. package/dist/{KioskDevicesView.vue_vue_type_script_setup_true_lang-B1sNvlUC.js → KioskDevicesView.vue_vue_type_script_setup_true_lang-dF1jgi53.js} +2 -2
  4. package/dist/{KioskSettingView-BE_pMA-i.js → KioskSettingView-8GY7AT-N.js} +128 -126
  5. package/dist/{KioskView-U-Wg8oMC.js → KioskView-DmaCjLcw.js} +4 -4
  6. package/dist/{OrderSettingsView-BWzaITT6.js → OrderSettingsView-BZcU4t9L.js} +28631 -24307
  7. package/dist/{app-CFfgPAd8.js → app-EGmxrjDM.js} +392 -228
  8. package/dist/app.js +1 -1
  9. package/dist/{dayjs.min-CuRr-wlf.js → dayjs.min-lCwCAXUZ.js} +1 -1
  10. package/dist/frontend/mf-order/src/api/reservation/index.d.ts +8 -0
  11. package/dist/frontend/mf-order/src/app.d.ts +164 -0
  12. package/dist/frontend/mf-order/src/main.d.ts +164 -0
  13. package/dist/frontend/mf-order/src/views/order-settings/reservation/CopySettingsSheet.vue.d.ts +186 -0
  14. package/dist/frontend/mf-order/src/views/order-settings/reservation/CustomSelect.vue.d.ts +15 -0
  15. package/dist/frontend/mf-order/src/views/order-settings/reservation/CustomTimePicker.vue.d.ts +10 -0
  16. package/dist/frontend/mf-order/src/views/order-settings/reservation/ReservationSetting.vue.d.ts +2 -0
  17. package/dist/{index-Bj0bCGTm.js → index-CWrX79Jg.js} +8 -8
  18. package/dist/{menu.dto-DAh1J2ES.js → menu.dto-CgymySda.js} +47093 -44304
  19. package/dist/package/entity/index.d.ts +5 -0
  20. package/dist/package/entity/order-setting/order-setting.do.d.ts +861 -0
  21. package/dist/package/entity/order-setting/reservationV2/reservation.do.d.ts +1269 -0
  22. package/dist/package/entity/reservation/reservation.do.d.ts +101 -0
  23. package/dist/package/entity/reservation/reservation.dto.d.ts +325 -0
  24. package/dist/package/entity/reservation/reservation.enum.d.ts +3 -0
  25. package/dist/package/entity/reservation/reservation.utils.d.ts +152 -0
  26. package/dist/style.css +1 -0
  27. package/package.json +1 -1
  28. package/src/api/reservation/index.ts +28 -0
  29. package/src/assets/images/not-found.png +0 -0
  30. package/src/locales/en-US.json +56 -0
  31. package/src/locales/th-TH.json +54 -0
  32. package/src/locales/zh-CN.json +54 -0
  33. package/src/views/kiosk/settings/KioskSettingView.vue +16 -14
  34. package/src/views/order-settings/OrderSettingsView.vue +6 -1
  35. package/src/views/order-settings/reservation/CopySettingsSheet.vue +256 -0
  36. package/src/views/order-settings/reservation/CustomSelect.vue +99 -0
  37. package/src/views/order-settings/reservation/CustomTimePicker.vue +231 -0
  38. package/src/views/order-settings/reservation/ReservationSetting.vue +1311 -0
  39. package/tsconfig.app.json +8 -6
  40. package/dist/frontend/mf-order/tsconfig.app.tsbuildinfo +0 -1
@@ -0,0 +1,231 @@
1
+ <script setup lang="ts">
2
+ import { ref, computed, onMounted, onUnmounted, nextTick } from 'vue'
3
+
4
+ const props = defineProps<{
5
+ modelValue: string
6
+ minTime?: string // Optional minimum time (HH:MM format)
7
+ }>()
8
+
9
+ const emit = defineEmits<{
10
+ (e: 'update:modelValue', value: string): void
11
+ }>()
12
+
13
+ const isOpen = ref(false)
14
+ const inputRef = ref<any>(null)
15
+ const dropdownRef = ref<HTMLDivElement | null>(null)
16
+
17
+ // Generate time options in 30-minute intervals
18
+ const timeOptions = computed(() => {
19
+ const options: string[] = []
20
+ for (let hour = 0; hour < 24; hour++) {
21
+ for (let minute = 0; minute < 60; minute += 30) {
22
+ const timeString = `${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`
23
+ options.push(timeString)
24
+ }
25
+ }
26
+
27
+ options.push('23:59')
28
+
29
+ // Filter out times earlier than minTime if provided
30
+ if (props.minTime) {
31
+ return options.filter((time) => isTimeGreaterOrEqual(time, props.minTime!))
32
+ }
33
+
34
+ return options
35
+ })
36
+
37
+ // Helper function to compare times in HH:MM format
38
+ function isTimeGreaterOrEqual(time1: string, time2: string): boolean {
39
+ const [hours1, minutes1] = time1.split(':').map(Number)
40
+ const [hours2, minutes2] = time2.split(':').map(Number)
41
+
42
+ const totalMinutes1 = hours1 * 60 + minutes1
43
+ const totalMinutes2 = hours2 * 60 + minutes2
44
+
45
+ return totalMinutes1 >= totalMinutes2
46
+ }
47
+
48
+ const displayValue = computed({
49
+ get: () => props.modelValue || '',
50
+ set: (value: string) => {
51
+ emit('update:modelValue', value)
52
+ }
53
+ })
54
+
55
+ function selectTime(time: string) {
56
+ displayValue.value = time
57
+ isOpen.value = false
58
+ }
59
+
60
+ function handleClickOutside(event: MouseEvent) {
61
+ const target = event.target as Node
62
+ const wrapperElement = inputRef.value?.$el || inputRef.value
63
+
64
+ if (
65
+ dropdownRef.value &&
66
+ wrapperElement &&
67
+ !dropdownRef.value.contains(target) &&
68
+ !wrapperElement.contains(target)
69
+ ) {
70
+ isOpen.value = false
71
+ }
72
+ }
73
+
74
+ function handleFocus() {
75
+ isOpen.value = true
76
+ }
77
+
78
+ function toggleDropdown(event?: Event) {
79
+ event?.stopPropagation()
80
+ // Close all other open dropdowns by dispatching a global event
81
+ if (!isOpen.value) {
82
+ window.dispatchEvent(new CustomEvent('closeTimePickers'))
83
+ }
84
+ isOpen.value = !isOpen.value
85
+
86
+ // Scroll to selected time when opening
87
+ if (isOpen.value) {
88
+ nextTick(() => {
89
+ scrollToSelectedTime()
90
+ })
91
+ }
92
+ }
93
+
94
+ function scrollToSelectedTime() {
95
+ const scrollContainer = dropdownRef.value?.querySelector('.overflow-y-auto')
96
+ if (!scrollContainer) return
97
+
98
+ const selectedElement = scrollContainer.querySelector('[data-selected="true"]')
99
+ if (selectedElement) {
100
+ selectedElement.scrollIntoView({ block: 'center' })
101
+ }
102
+ }
103
+
104
+ function handleInputValue(value: string) {
105
+ let formattedValue = value.replace(/[^\d:]/g, '')
106
+
107
+ // Auto-format as user types
108
+ if (formattedValue.length === 2 && !formattedValue.includes(':')) {
109
+ formattedValue = formattedValue + ':'
110
+ }
111
+
112
+ // Limit to HH:MM format
113
+ if (formattedValue.length > 5) {
114
+ formattedValue = formattedValue.slice(0, 5)
115
+ }
116
+
117
+ displayValue.value = formattedValue
118
+ }
119
+
120
+ function handleCloseTimePickers() {
121
+ isOpen.value = false
122
+ }
123
+
124
+ onMounted(() => {
125
+ document.addEventListener('click', handleClickOutside)
126
+ window.addEventListener('closeTimePickers', handleCloseTimePickers)
127
+ })
128
+
129
+ onUnmounted(() => {
130
+ document.removeEventListener('click', handleClickOutside)
131
+ window.removeEventListener('closeTimePickers', handleCloseTimePickers)
132
+ })
133
+ </script>
134
+
135
+ <template>
136
+ <div class="relative w-full">
137
+ <div @click="toggleDropdown" class="cursor-pointer relative">
138
+ <FmTextField
139
+ ref="inputRef"
140
+ :model-value="displayValue"
141
+ @update:model-value="handleInputValue"
142
+ @focus="handleFocus"
143
+ placeholder="HH:MM"
144
+ class="time-picker-field"
145
+ :class="{
146
+ focused: isOpen
147
+ }"
148
+ maxlength="5"
149
+ >
150
+ </FmTextField>
151
+ <FmIcon
152
+ class="absolute right-1 transition-all duration-200"
153
+ name="chevron_right"
154
+ :class="{ 'rotate-[-90deg] top-[4px]': isOpen, 'rotate-[90deg] top-[5px]': !isOpen }"
155
+ />
156
+ </div>
157
+
158
+ <div
159
+ v-if="isOpen"
160
+ ref="dropdownRef"
161
+ class="absolute z-50 w-full mt-2 bg-white border border-gray-200 rounded-md shadow-lg max-h-[240px] overflow-hidden"
162
+ >
163
+ <div class="max-h-[240px] overflow-y-auto scrollbar-thin">
164
+ <div
165
+ v-for="time in timeOptions"
166
+ :key="time"
167
+ @click.stop="selectTime(time)"
168
+ :data-selected="time === displayValue"
169
+ class="px-3 py-2 text-sm cursor-pointer transition-colors hover:bg-gray-50"
170
+ :class="{
171
+ 'bg-orange-50 text-orange-600 font-medium': time === displayValue
172
+ }"
173
+ >
174
+ {{ time }}
175
+ </div>
176
+ </div>
177
+ </div>
178
+ </div>
179
+ </template>
180
+
181
+ <style scoped>
182
+ /* Custom scrollbar for dropdown - target the scrollable container */
183
+ .scrollbar-thin::-webkit-scrollbar {
184
+ width: 6px;
185
+ }
186
+
187
+ .scrollbar-thin::-webkit-scrollbar-track {
188
+ background: transparent;
189
+ border-radius: 3px;
190
+ margin: 4px 0;
191
+ }
192
+
193
+ .scrollbar-thin::-webkit-scrollbar-thumb {
194
+ background: #d1d5db;
195
+ border-radius: 3px;
196
+ }
197
+
198
+ .scrollbar-thin::-webkit-scrollbar-thumb:hover {
199
+ background: #9ca3af;
200
+ }
201
+
202
+ /* Override FmTextField styling for orange theme */
203
+ .time-picker-field :deep(.fm-text-field-input) {
204
+ width: 140px !important;
205
+ border-width: 2px;
206
+ border-radius: 0.75rem;
207
+ padding: 12px 16px;
208
+ font-size: 1.125rem;
209
+ transition: all 0.2s;
210
+ }
211
+
212
+ .time-picker-field :deep(.fm-text-field-input):not(:focus):not(:focus-within) {
213
+ border-color: rgb(209 213 219);
214
+ /* gray-300 */
215
+ background-color: white;
216
+ }
217
+
218
+ .time-picker-field :deep(.fm-text-field-input):not(:focus):not(:focus-within):hover {
219
+ border-color: rgb(156 163 175);
220
+ /* gray-400 */
221
+ }
222
+
223
+ .time-picker-field.focused :deep(.fm-text-field-input),
224
+ .time-picker-field :deep(.fm-text-field-input):focus,
225
+ .time-picker-field :deep(.fm-text-field-input):focus-within {
226
+ border-color: rgb(249 115 22) !important;
227
+ /* orange-500 */
228
+ background-color: rgb(255 247 237) !important;
229
+ /* orange-50 */
230
+ }
231
+ </style>