esoftplay-event 0.0.1-c → 0.0.1-d

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.
package/event/detail.tsx CHANGED
@@ -24,41 +24,6 @@ import React, { useEffect } from 'react';
24
24
  import { Linking, Pressable, Text, TouchableOpacity, View } from 'react-native';
25
25
  import MapView, { Marker } from 'react-native-maps';
26
26
 
27
- function timezoneCorrection(input: string | Date, timezone: string): string {
28
- const tzMap: Record<string, string> = {
29
- 'GMT+7': 'Asia/Jakarta',
30
- 'GMT+8': 'Asia/Singapore',
31
- 'GMT+9': 'Asia/Tokyo'
32
- };
33
-
34
- const tzString = tzMap[timezone] || 'Asia/Jakarta';
35
-
36
- let date: Date;
37
- if (typeof input === 'string') {
38
- const iso = input.replace(' ', 'T') + '+07:00';
39
- date = new Date(iso);
40
- } else {
41
- date = input;
42
- }
43
-
44
- const options: Intl.DateTimeFormatOptions = {
45
- timeZone: tzString,
46
- year: 'numeric',
47
- month: '2-digit',
48
- day: '2-digit',
49
- hour: '2-digit',
50
- minute: '2-digit',
51
- second: '2-digit',
52
- hour12: false,
53
- };
54
-
55
- const formatted = date.toLocaleString('en-GB', options)
56
- const [datePart, timePart] = formatted.split(', ')
57
- const [day, month, year] = datePart.split('/')
58
-
59
- return `${year}-${month}-${day} ${timePart}`
60
- }
61
-
62
27
  export interface EventDetailProps {
63
28
 
64
29
  }
@@ -148,15 +113,6 @@ export default function m(props: EventDetailProps): any {
148
113
  }
149
114
 
150
115
  const date = moment().localeFormat('YYYY-MM-DD HH:mm:ss')
151
- const startBooking = result?.start_booking;
152
- const startDate: any = new Date(startBooking);
153
- const currentDate: any = new Date();
154
-
155
- // Hitung selisih hari antara tanggal sekarang dan startBooking
156
- const diffTime = startDate - currentDate;
157
- const diffDays = diffTime / (1000 * 60 * 60 * 24);
158
-
159
- esp.log(result);
160
116
 
161
117
  return (
162
118
  <View style={{ flex: 1, backgroundColor: '#fff' }} >
package/event/order.tsx CHANGED
@@ -128,7 +128,9 @@ export default function m(props: EventOrderProps): any {
128
128
  function renderItem(item: any) {
129
129
  return (
130
130
  <EventOrder_item item={item} onPress={() => {
131
- LibNavigation.navigate('event/order_detail', { url: item.url })
131
+ esp.log(item);
132
+ // 7 pembayaran kadaluarsa
133
+ LibNavigation.navigate(status == "7" ? 'event/order_detail_waiting' : 'event/order_detail', { url: item.url })
132
134
  }} />
133
135
  )
134
136
  }
@@ -133,7 +133,7 @@ export default function m(props: EventOrder_detailProps): any {
133
133
  function loadData(): void {
134
134
  new LibCurl(url + ((url.includes("?") ? "&" : "?") + 't=' + new Date().getTime()), null, (res: any) => {
135
135
  setResult(res)
136
- // esp.log(res);
136
+ esp.log(res);
137
137
 
138
138
  new LibCurl(res?.url_coupon, null, (ress: any) => {
139
139
  setCoupons(ress)
@@ -63,10 +63,13 @@ export default function m(props: EventOrder_waitingProps): any {
63
63
  function loadData() {
64
64
  EventOrderProperty.subscribe().trigger()
65
65
  new LibCurl(url + ((url.includes("?") ? "&" : "?") + 't=' + new Date().getTime()), null, (res) => {
66
- // esp.log(res);
66
+ esp.log(res);
67
67
  setResult(res)
68
+ if (res?.status != 0) {
69
+ LibAutoreload.clear()
70
+ }
71
+
68
72
  if (res?.status == 1) {
69
- // LibAutoreload.clear()
70
73
  LibNavigation.backToRoot()
71
74
  LibNavigation.navigate('user/profile')
72
75
  LibNavigation.navigate('event/order')
@@ -381,7 +384,7 @@ export default function m(props: EventOrder_waitingProps): any {
381
384
  }
382
385
 
383
386
  {
384
- result?.payment?.payment_type != 3 && result?.payment?.payment_type != 4 && result?.payment?.payment_type != 11 && result?.payment?.payment_type != 13 && result?.payment?.payment_type != 14 &&
387
+ result?.status == 0 && result?.payment?.payment_type != 3 && result?.payment?.payment_type != 4 && result?.payment?.payment_type != 11 && result?.payment?.payment_type != 13 && result?.payment?.payment_type != 14 &&
385
388
  <>
386
389
  <View style={{ height: 3, backgroundColor: "#f6f6f6" }} />
387
390
 
@@ -425,18 +428,24 @@ export default function m(props: EventOrder_waitingProps): any {
425
428
  result?.payment?.payment_type == 13 &&
426
429
  <>
427
430
  <View style={{ height: 3, backgroundColor: "#f6f6f6" }} />
428
-
429
431
  <TouchableOpacity
430
432
  onPress={() => {
431
- Linking.openURL(result?.params?.url_mobile)
433
+ if (result?.params?.url_mobile != null) {
434
+ Linking.openURL(result?.params?.url_mobile)
435
+ } else if (result?.params?.url_web != null) {
436
+ Linking.openURL(result?.params?.url_web)
437
+ }
432
438
  }}
433
439
  style={{ marginTop: 15, borderRadius: 10, borderWidth: 2, overflow: 'hidden', borderColor: "#f6f6f6" }}>
434
440
  <View style={{ padding: 15, backgroundColor: '#000', justifyContent: 'center', alignContent: 'center', alignItems: 'center' }}>
435
441
  <Text allowFontScaling={false} style={{ flex: 1, alignContent: 'center', alignItems: 'center', fontWeight: 'bold', fontSize: 16, fontStyle: "normal", letterSpacing: 0, color: "#fff" }}>{esp.lang("event/order_detail_waiting", "scan_or_tap")}</Text>
436
442
  </View>
437
- <View style={{ margin: 15, alignSelf: 'center' }}>
438
- <QRCode ecl="H" size={250} value={result?.params?.qr} />
439
- </View>
443
+ {
444
+ result?.params?.qr != null &&
445
+ <View style={{ margin: 15, alignSelf: 'center' }}>
446
+ <QRCode ecl="H" size={250} value={result?.params?.qr} />
447
+ </View>
448
+ }
440
449
 
441
450
  </TouchableOpacity>
442
451
 
@@ -444,7 +453,10 @@ export default function m(props: EventOrder_waitingProps): any {
444
453
  }
445
454
 
446
455
  <View style={{ height: 3, backgroundColor: "#f6f6f6" }} />
447
- <Text allowFontScaling={false} style={{ fontSize: 10, fontWeight: "normal", fontStyle: "normal", letterSpacing: 0, color: "#9b9b9b", marginTop: 14 }}>{esp.lang("event/order_detail", "Checked_within_10_minutes_after_payment_is_made")}</Text>
456
+ {
457
+ result?.status == 0 &&
458
+ <Text allowFontScaling={false} style={{ fontSize: 10, fontWeight: "normal", fontStyle: "normal", letterSpacing: 0, color: "#9b9b9b", marginTop: 14 }}>{esp.lang("event/order_detail", "Checked_within_10_minutes_after_payment_is_made")}</Text>
459
+ }
448
460
  {
449
461
  result?.payment?.description != null &&
450
462
  <TouchableOpacity onPress={() => {
@@ -0,0 +1,313 @@
1
+ // withHooks
2
+ import { Canvas, Group, RoundedRect, Text, useFont } from '@shopify/react-native-skia';
3
+ import { EventButton } from 'esoftplay/cache/event/button/import';
4
+ import { EventHeader } from 'esoftplay/cache/event/header/import';
5
+ import { EventMessage } from 'esoftplay/cache/event/message/import';
6
+ import { LibCurl } from 'esoftplay/cache/lib/curl/import';
7
+ import { LibIcon } from 'esoftplay/cache/lib/icon/import';
8
+ import { LibNavigation } from 'esoftplay/cache/lib/navigation/import';
9
+ import { LibStyle } from 'esoftplay/cache/lib/style/import';
10
+ import { LibTextstyle } from 'esoftplay/cache/lib/textstyle/import';
11
+ import { LibToastProperty } from 'esoftplay/cache/lib/toast/import';
12
+ import { UseMap } from 'esoftplay/cache/use/map/import';
13
+ import esp from 'esoftplay/esp';
14
+ import useSafeState from 'esoftplay/state';
15
+ import React, { useCallback, useEffect, useState } from 'react';
16
+ import { Dimensions, Pressable, ScrollView, View } from 'react-native';
17
+ import { TapGestureHandler, TapGestureHandlerStateChangeEvent } from 'react-native-gesture-handler';
18
+
19
+
20
+ export interface EventSeat_map_newArgs {
21
+
22
+ }
23
+ export interface EventSeat_map_newProps {
24
+
25
+ }
26
+ export default function m(props: any): any {
27
+ const { dataTicket, url } = LibNavigation.getArgsAll<any>(props)
28
+ const qty = dataTicket?.qty
29
+
30
+ const deviceWidth = Dimensions.get('window').width;
31
+ const [scale, setScale] = useState(1);
32
+ const [boundingBox, setBoundingBox] = useSafeState({ "x1": 1, "x2": 2, "y1": 1, "y2": 2 })
33
+ const [data, setData, getData] = useSafeState<[number, number, string, number][]>([])
34
+ const initialBoxSize = 30;
35
+ const contentWidth = (boundingBox.x2 - (boundingBox.x1 - 1.1)) * initialBoxSize
36
+ const [, setSelectedSeat, getSelectedSeat] = useSafeState<any>([])
37
+ const [errBookedSeat, setErrBookedSeat] = useSafeState()
38
+
39
+ // Scale boxSize so that contentWidth fits deviceWidth
40
+ const scaleToFit = deviceWidth / contentWidth;
41
+ const boxSize = initialBoxSize * scaleToFit;
42
+
43
+ // Recalculate xs, ys, width, height with scaled boxSize
44
+ const xsScaled = getData()?.map(([x]) => isNaN(x) ? 0 : (boxSize) + (x * boxSize));
45
+ const ysScaled = getData()?.map(([_, y]) => isNaN(y) ? 0 : (boxSize) + (y * boxSize));
46
+
47
+ const width = Math.max(deviceWidth, xsScaled.length && xsScaled.every(v => !isNaN(v)) ? Math.max(...xsScaled) + boxSize : boxSize * 2);
48
+ const height = ysScaled.length && ysScaled.every(v => !isNaN(v)) ? Math.max(...ysScaled) + boxSize : boxSize * 2;
49
+
50
+
51
+ // Preload all possible fonts at top level (to avoid render hook errors)
52
+ const fontSizes = [boxSize * 0.35, boxSize * 0.30, boxSize * 0.27, boxSize * 0.25, boxSize * 0.20];
53
+ const fonts = fontSizes.map(size => useFont(esp.assets('fonts/MonoSpace.ttf'), size));
54
+
55
+ const getFontByLength = (length: number) => {
56
+ if (length <= 2) return fonts[0];
57
+ if (length == 3) return fonts[1];
58
+ if (length == 4) return fonts[2];
59
+ if (length == 5) return fonts[3];
60
+ return fonts[4];
61
+ };
62
+
63
+ const getFontSizeByLength = (length: number) => {
64
+ if (length <= 2) return fontSizes[0];
65
+ if (length == 3) return fontSizes[1];
66
+ if (length == 4) return fontSizes[2];
67
+ if (length == 5) return fontSizes[3];
68
+ return fontSizes[4];
69
+ };
70
+
71
+
72
+ // const size: any = {
73
+ // 1: useFont(esp.assets('fonts/MonoSpace.ttf'), boxSize * 0.3),
74
+ // 2: useFont(esp.assets('fonts/MonoSpace.ttf'), boxSize * 0.3),
75
+ // 3: useFont(esp.assets('fonts/MonoSpace.ttf'), boxSize * 0.25),
76
+ // 4: useFont(esp.assets('fonts/MonoSpace.ttf'), boxSize * 0.27),
77
+ // 5: useFont(esp.assets('fonts/MonoSpace.ttf'), boxSize * 0.25),
78
+ // 6: useFont(esp.assets('fonts/MonoSpace.ttf'), boxSize * 0.15),
79
+ // }
80
+
81
+ const handleTap = useCallback((event: TapGestureHandlerStateChangeEvent) => {
82
+ if (event.nativeEvent.state !== 5) return;
83
+ // Adjust tap coordinates for scale
84
+ const x = event.nativeEvent.x / scale;
85
+ const y = event.nativeEvent.y / scale;
86
+ for (let i = 0; i < getData()?.length; i++) {
87
+ const [sx, sy, seatName, status] = getData()?.[i];
88
+ const xSize = (boxSize / 2) + (sx * boxSize);
89
+ const ySize = (boxSize / 2) + (sy * boxSize);
90
+
91
+ if (x >= xSize && x <= xSize + boxSize && y >= ySize && y <= ySize + boxSize) {
92
+ if (status == 0) {
93
+ setSelectedSeat((prev: any) => {
94
+ if (!prev?.includes(seatName)) {
95
+ if (prev?.length < qty) {
96
+ return [...prev, seatName];
97
+ }
98
+ LibToastProperty.show(esp.lang("event/seat_map", "max_seat", qty))
99
+ return prev;
100
+ }
101
+ return prev.filter((s: string) => s != seatName);
102
+ });
103
+ }
104
+ return;
105
+ }
106
+
107
+ }
108
+ }, [data, boxSize, scale]);
109
+
110
+ useEffect(() => {
111
+ loadDataSeatmapBooked()
112
+ return () => LibNavigation.cancelBackResult(LibNavigation.getResultKey(props))
113
+ }, [])
114
+
115
+ function updateIndexByRes(data: any, res: any) {
116
+ const resArr = res.split(",").map((item: any) => item.trim()); // biar aman dari spasi
117
+ return data.map((row: any) => {
118
+ if (resArr.includes(row[2])) {
119
+ return [row[0], row[1], row[2], 3];
120
+ }
121
+ return row;
122
+ });
123
+ }
124
+
125
+ function loadDataSeatmap(seatBooked: any) {
126
+ new LibCurl("v3/event_seat", {
127
+ event_id: dataTicket?.event_id,
128
+ price_id: dataTicket?.selected_ticket?.price_id,
129
+ ondate: dataTicket?.selected_ticket?.list?.ondate
130
+ }, (res, msg) => {
131
+ // esp.log(res);
132
+ setBoundingBox(res.metadata.bounding_box)
133
+ let x = res.layout.split(';').map((item: any) => item.split(',')).map(([x, y, seatName, status]: any) => [Number(x), Number(y), seatName, Number(status)])
134
+ let updated = updateIndexByRes(x, seatBooked)
135
+ setData(updated)
136
+ })
137
+ }
138
+
139
+ function loadDataSeatmapBooked() {
140
+ new LibCurl("v3/event_seat_booked", {
141
+ event_id: dataTicket?.event_id,
142
+ price_id: dataTicket?.selected_ticket?.price_id,
143
+ ondate: dataTicket?.selected_ticket?.list?.ondate
144
+ }, (res, msg) => {
145
+ loadDataSeatmap(res)
146
+ setErrBookedSeat(undefined)
147
+ }, (err) => {
148
+ setErrBookedSeat(err?.message)
149
+ })
150
+ }
151
+
152
+ if (errBookedSeat) {
153
+ return (
154
+ <View style={{ flex: 1, backgroundColor: LibStyle.colorBgGrey }}>
155
+ <EventHeader title={esp.lang("event/seat_map", "header_title")} />
156
+ <View style={{ flex: 1 }}>
157
+ <EventMessage
158
+ message={errBookedSeat}
159
+ children={
160
+ <EventButton
161
+ label='Coba lagi'
162
+ style={{ marginHorizontal: 15 }}
163
+ onPress={() => {
164
+ loadDataSeatmapBooked()
165
+ }}
166
+ />
167
+ }
168
+ />
169
+ </View>
170
+ </View>
171
+ )
172
+ }
173
+
174
+ return (
175
+ <View key={scale} style={{ flex: 1, backgroundColor: LibStyle.colorBgGrey }} >
176
+ <EventHeader title={esp.lang("event/seat_map", "header_title")} />
177
+ <View style={{ flex: 1 }}>
178
+ <View style={{ marginBottom: 5, }}>
179
+ <ScrollView style={{ padding: 10, paddingLeft: 0, }} horizontal>
180
+ <UseMap
181
+ data={getLegends()}
182
+ renderItem={(item) => (
183
+ <View style={{ flexDirection: 'row', alignItems: 'center', marginLeft: 15, marginRight: 5 }} >
184
+ <View style={{ height: 20, width: 20, borderRadius: 2, borderWidth: 0.5, backgroundColor: item[0], marginRight: 8 }} />
185
+ <LibTextstyle textStyle='caption1' text={item[1]} />
186
+ </View>
187
+ )}
188
+ />
189
+ </ScrollView>
190
+ </View>
191
+ <ScrollView horizontal >
192
+ <ScrollView >
193
+ <TapGestureHandler onHandlerStateChange={handleTap}>
194
+ <View>
195
+ <Canvas
196
+ style={{
197
+ width: width * scale,
198
+ height: height * scale,
199
+ padding: 10,
200
+ backgroundColor: LibStyle.colorBgGrey,
201
+
202
+ }}>
203
+ {
204
+ getData()?.map(([x, y, name, status], i) => {
205
+ const isSelected = getSelectedSeat()?.includes(name)
206
+ const color = isSelected ? "#8EF67B" : getColorByStatus(status)
207
+ const xSize = (boxSize / 2) + (x * boxSize)
208
+ const ySize = (boxSize / 2) + (y * boxSize)
209
+
210
+ const fontSize = getFontSizeByLength(name?.length);
211
+ const font = getFontByLength(name?.length);
212
+
213
+ const textWidthApprox = fontSize * name?.length * 0.6;
214
+ const textX = xSize + (boxSize - textWidthApprox) / 2;
215
+
216
+ return (
217
+ <Group key={i}>
218
+ <RoundedRect
219
+ x={xSize - 1}
220
+ r={(boxSize + 2) * 0.1}
221
+ y={ySize - 1}
222
+ width={boxSize + 2}
223
+ transform={[{ scale }]}
224
+ height={boxSize + 2}
225
+ color={"#999"} />
226
+ <RoundedRect
227
+ x={xSize}
228
+ r={boxSize * 0.1}
229
+ y={ySize}
230
+ width={boxSize}
231
+ transform={[{ scale }]}
232
+ height={boxSize}
233
+ color={color} />
234
+ {name && font && (
235
+ <Text
236
+ x={textX}
237
+ y={(ySize) + boxSize * 0.60}
238
+ color={"#020202"}
239
+ text={name}
240
+ transform={[{ scale }]}
241
+ font={font} />
242
+ )}
243
+ </Group>
244
+ )
245
+ })
246
+ }
247
+ </Canvas>
248
+ </View>
249
+ </TapGestureHandler>
250
+ </ScrollView>
251
+ </ScrollView>
252
+ <View style={{ flexDirection: 'row', marginHorizontal: 12, height: 40, borderColor: '#060606', borderWidth: 1, borderRadius: 5, alignItems: 'center' }} >
253
+ <Pressable onPress={() => setScale((x) => x - 0.3)} style={{ height: 40, width: 40, alignItems: 'center', justifyContent: 'center' }} >
254
+ <LibIcon.SimpleLineIcons name='magnifier-remove' />
255
+ </Pressable>
256
+ <Pressable onPress={() => setScale((x) => x + 0.3)} style={{ height: 40, width: 40, alignItems: 'center', justifyContent: 'center' }} >
257
+ <LibIcon.SimpleLineIcons name='magnifier-add' />
258
+ </Pressable>
259
+ <View style={{ height: 40, width: 1, backgroundColor: '#060606', marginRight: 12 }} />
260
+ {/* <Text style={{}} >{esp.lang("event/seat_map", "selected", String(data.filter((x) => x == -1).length), qty)}</Text> */}
261
+ <LibTextstyle textStyle='callout'>{esp.lang("event/seat_map", "selected", String(getSelectedSeat().length), qty)}</LibTextstyle>
262
+ </View>
263
+ <EventButton
264
+ backgroundColor={getSelectedSeat()?.length < qty ? "#999" : LibStyle.colorPrimary}
265
+ testID={"save_btn"}
266
+ style={{ margin: 7 }}
267
+ label={esp.lang("event/seat_map", "save")}
268
+ onPress={() => {
269
+ let value = {
270
+ seat_label: getSelectedSeat()
271
+ }
272
+ if (getSelectedSeat()?.length < qty) {
273
+ LibToastProperty.show(esp.lang("event/seat_map", "seat_more", (qty - (getSelectedSeat()?.length)).toString()))
274
+ } else {
275
+ LibNavigation.sendBackResult(value, LibNavigation.getResultKey(props))
276
+ }
277
+ }}
278
+ />
279
+ </View>
280
+ </View>
281
+ )
282
+ }
283
+
284
+ function getLegends() {
285
+ const colors: any = [
286
+ ["#fff", esp.lang("event/seat_map", "available"), 0],
287
+ ["#8EF67B", esp.lang("event/seat_map", "chosen"), "-1"],
288
+ ["#2EBBE8", esp.lang("event/seat_map", "reserved"), 3],
289
+ ["#6C432C", esp.lang("event/seat_map", "chosen_by"), 7],
290
+ ["#f1f2f3", esp.lang("event/seat_map", "way"), 5],
291
+ ["#9FA1A4", esp.lang("event/seat_map", "not_sold"), 1],
292
+ ["#6B71E6", esp.lang("event/seat_map", "seat_hold"), 2],
293
+ ["#FF4866", esp.lang("event/seat_map", "wall"), 6],
294
+ ["#FFA601", esp.lang("event/seat_map", "other_type"), 4],
295
+ ["purple", esp.lang("event/seat_map", "stage"), 8]
296
+ ]
297
+ return colors
298
+ }
299
+
300
+ function getColorByStatus(statuses: number) {
301
+ const colors: any = {
302
+ 8: 'purple',
303
+ 0: '#fff',
304
+ 1: "#9FA1A4",
305
+ 2: "#6B71E6",
306
+ 3: "#2EBBE8",
307
+ 4: "#FFA601",
308
+ 5: "#fff",
309
+ 6: "#FF4866",
310
+ 7: "#6C432C"
311
+ }
312
+ return colors[statuses]
313
+ }
package/event/test.tsx CHANGED
@@ -1,155 +1,240 @@
1
- // // withHooks
2
- // import { Canvas, Group, RoundedRect, Text, useFont } from '@shopify/react-native-skia';
3
- // import { LibCurl } from 'esoftplay/cache/lib/curl/import';
4
- // import { LibIcon } from 'esoftplay/cache/lib/icon/import';
5
- // import useSafeState from 'esoftplay/state';
6
- // import React, { useCallback, useEffect, useState } from 'react';
7
- // import { Dimensions, Pressable, ScrollView, View } from 'react-native';
8
- // import { TapGestureHandler, TapGestureHandlerStateChangeEvent } from 'react-native-gesture-handler';
9
-
10
-
11
- // export interface EventSeat_map_matrixArgs {
12
-
13
- // }
14
- // export interface EventSeat_map_matrixProps {
15
-
16
- // }
17
- // export default function m(props: any): any {
18
- // const deviceWidth = Dimensions.get('window').width;
19
- // const [selectedIdx, setSelectedIdx] = useState<number | null>(null);
20
- // const [scale, setScale] = useState(1);
21
- // const [boundingBox, setBoundingBox] = useSafeState({ "x1": 1, "x2": 2, "y1": 1, "y2": 2 })
22
- // const [data, setData] = useSafeState<[number, number, string, number][]>([])
23
- // const initialBoxSize = 30;
24
- // const contentWidth = (boundingBox.x2 - (boundingBox.x1 - 1.1)) * initialBoxSize
25
-
26
- // // Scale boxSize so that contentWidth fits deviceWidth
27
- // const scaleToFit = deviceWidth / contentWidth;
28
- // const boxSize = initialBoxSize * scaleToFit;
29
-
30
- // // Recalculate xs, ys, width, height with scaled boxSize
31
- // const xsScaled = data.map(([x]) => isNaN(x) ? 0 : (boxSize) + (x * boxSize));
32
- // const ysScaled = data.map(([_, y]) => isNaN(y) ? 0 : (boxSize) + (y * boxSize));
33
-
34
- // const width = Math.max(deviceWidth, xsScaled.length && xsScaled.every(v => !isNaN(v)) ? Math.max(...xsScaled) + boxSize : boxSize * 2);
35
- // const height = ysScaled.length && ysScaled.every(v => !isNaN(v)) ? Math.max(...ysScaled) + boxSize : boxSize * 2;
36
-
37
- // const fontSize: any = {
38
- // 1: useFont(require('../../assets/fonts/MonoSpace.ttf'), boxSize * 0.3),
39
- // 2: useFont(require('../../assets/fonts/MonoSpace.ttf'), boxSize * 0.3),
40
- // 3: useFont(require('../../assets/fonts/MonoSpace.ttf'), boxSize * 0.25),
41
- // 4: useFont(require('../../assets/fonts/MonoSpace.ttf'), boxSize * 0.2),
42
- // 5: useFont(require('../../assets/fonts/MonoSpace.ttf'), boxSize * 0.2),
43
- // 6: useFont(require('../../assets/fonts/MonoSpace.ttf'), boxSize * 0.15),
44
- // }
45
- // const handleTap = useCallback((event: TapGestureHandlerStateChangeEvent) => {
46
- // if (event.nativeEvent.state !== 5) return;
47
- // // Adjust tap coordinates for scale
48
- // const x = event.nativeEvent.x / scale;
49
- // const y = event.nativeEvent.y / scale;
50
- // for (let i = 0; i < data.length; i++) {
51
- // const [sx, sy, seatName] = data[i];
52
- // const xSize = (boxSize / 2) + (sx * boxSize);
53
- // const ySize = (boxSize / 2) + (sy * boxSize);
54
- // if (x >= xSize && x <= xSize + boxSize && y >= ySize && y <= ySize + boxSize) {
55
- // setSelectedIdx(i);
56
- // return;
57
- // }
58
- // }
59
- // setSelectedIdx(null);
60
- // }, [data, boxSize, scale]);
61
-
62
-
63
- // useEffect(() => {
64
- // new LibCurl("v3/event_seat", {
65
- // event_id: 398,
66
- // price_id: 1922,
67
- // ondate: "0000-00-00"
68
- // }, (res, msg) => {
69
- // setBoundingBox(res.metadata.bounding_box)
70
- // console.log(JSON.stringify(res, undefined, 2))
71
- // setData(res.layout.split(';').map((item) => item.split(',')).map(([x, y, seatName, status]) => [Number(x), Number(y), seatName, Number(status)]))
72
- // })
73
- // }, [])
74
-
75
- // return (
76
- // <View key={scale} style={{ flex: 1 }} >
77
- // <ScrollView horizontal style={{ flex: 1 }}>
78
- // <ScrollView style={{ flex: 1 }}>
79
- // <TapGestureHandler onHandlerStateChange={handleTap}>
80
- // <View>
81
- // <Canvas
82
- // style={{
83
- // width: width * scale,
84
- // height: height * scale,
85
- // padding: 10,
86
- // backgroundColor: "#f1f2f3",
87
- // }}>
88
- // {
89
- // data.map(([x, y, name, status], i) => {
90
- // const color = selectedIdx == i ? "lime" : getColorByStatus(status)
91
- // const xSize = (boxSize / 2) + (x * boxSize)
92
- // const ySize = (boxSize / 2) + (y * boxSize)
93
- // return (
94
- // <Group key={i}>
95
- // <RoundedRect
96
- // x={xSize - 1}
97
- // r={(boxSize + 2) * 0.34}
98
- // y={ySize - 1}
99
- // width={boxSize + 2}
100
- // transform={[{ scale }]}
101
- // height={boxSize + 2}
102
- // color={"#999"} />
103
- // <RoundedRect
104
- // x={xSize}
105
- // r={boxSize * 0.32}
106
- // y={ySize}
107
- // width={boxSize}
108
- // transform={[{ scale }]}
109
- // height={boxSize}
110
- // color={color} />
111
- // {name && fontSize[name.length] && (
112
- // <Text
113
- // x={(xSize) + boxSize * (5 - name.length) * 0.1}
114
- // y={(ySize) + boxSize * 0.60}
115
- // color="#020202"
116
- // text={name}
117
- // transform={[{ scale }]}
118
- // font={fontSize[name.length]} />
119
- // )}
120
- // </Group>
121
- // )
122
- // })
123
- // }
124
- // </Canvas>
125
- // </View>
126
- // </TapGestureHandler>
127
- // </ScrollView>
128
- // </ScrollView>
129
- // <View style={{ flexDirection: "row" }} >
130
- // <Pressable onPress={() => setScale((x) => x - 0.3)} >
131
- // <LibIcon.AntDesign name='minuscircleo' />
132
- // </Pressable>
133
- // <Pressable onPress={() => setScale((x) => x + 0.3)} >
134
- // <LibIcon.AntDesign name='pluscircleo' />
135
- // </Pressable>
136
- // </View>
137
- // </View>
138
- // )
139
- // }
140
-
141
-
142
- // function getColorByStatus(statuses: number) {
143
- // const colors: any = {
144
- // 8: 'purple',
145
- // 0: "white",
146
- // 1: "#9FA1A4",
147
- // 2: "#6B71E6",
148
- // 3: "#2EBBE8",
149
- // 4: "#FFA601",
150
- // 5: "#fff",
151
- // 6: "#FF4866",
152
- // 7: "#6C432C"
153
- // }
154
- // return colors[statuses]
155
- // }
1
+ // withHooks
2
+ import { Canvas, Group, RoundedRect, Text, useFont } from '@shopify/react-native-skia';
3
+ import { EventButton } from 'esoftplay/cache/event/button/import';
4
+ import { EventHeader } from 'esoftplay/cache/event/header/import';
5
+ import { LibCurl } from 'esoftplay/cache/lib/curl/import';
6
+ import { LibIcon } from 'esoftplay/cache/lib/icon/import';
7
+ import { LibStyle } from 'esoftplay/cache/lib/style/import';
8
+ import { LibTextstyle } from 'esoftplay/cache/lib/textstyle/import';
9
+ import { UseMap } from 'esoftplay/cache/use/map/import';
10
+ import esp from 'esoftplay/esp';
11
+ import useLazyState from 'esoftplay/lazy';
12
+ import useSafeState from 'esoftplay/state';
13
+ import React, { useCallback, useEffect, useState } from 'react';
14
+ import { Dimensions, Pressable, ScrollView, View } from 'react-native';
15
+ import { TapGestureHandler, TapGestureHandlerStateChangeEvent } from 'react-native-gesture-handler';
16
+
17
+
18
+ export interface EventSeat_map_matrixArgs {
19
+
20
+ }
21
+ export interface EventSeat_map_matrixProps {
22
+
23
+ }
24
+ export default function m(props: any): any {
25
+ const deviceWidth = Dimensions.get('window').width;
26
+ const [selectedIdx, setSelectedIdx] = useState<number | null>(null);
27
+ const [scale, setScale] = useState(1);
28
+ const [boundingBox, setBoundingBox] = useSafeState({ "x1": 1, "x2": 2, "y1": 1, "y2": 2 })
29
+ const [data, setData, getData] = useSafeState<[number, number, string, number][]>([])
30
+ const initialBoxSize = 30;
31
+ const contentWidth = (boundingBox.x2 - (boundingBox.x1 - 1.1)) * initialBoxSize
32
+ const [stage, setStage] = useLazyState('')
33
+
34
+ // Scale boxSize so that contentWidth fits deviceWidth
35
+ const scaleToFit = deviceWidth / contentWidth;
36
+ const boxSize = initialBoxSize * scaleToFit;
37
+
38
+ // Recalculate xs, ys, width, height with scaled boxSize
39
+ const xsScaled = data.map(([x]) => isNaN(x) ? 0 : (boxSize) + (x * boxSize));
40
+ const ysScaled = data.map(([_, y]) => isNaN(y) ? 0 : (boxSize) + (y * boxSize));
41
+
42
+ const width = Math.max(deviceWidth, xsScaled.length && xsScaled.every(v => !isNaN(v)) ? Math.max(...xsScaled) + boxSize : boxSize * 2);
43
+ const height = ysScaled.length && ysScaled.every(v => !isNaN(v)) ? Math.max(...ysScaled) + boxSize : boxSize * 2;
44
+
45
+ const size: any = {
46
+ 1: useFont(esp.assets('fonts/MonoSpace.ttf'), boxSize * 0.3),
47
+ 2: useFont(esp.assets('fonts/MonoSpace.ttf'), boxSize * 0.3),
48
+ 3: useFont(esp.assets('fonts/MonoSpace.ttf'), boxSize * 0.25),
49
+ 4: useFont(esp.assets('fonts/MonoSpace.ttf'), boxSize * 0.2),
50
+ 5: useFont(esp.assets('fonts/MonoSpace.ttf'), boxSize * 0.2),
51
+ 6: useFont(esp.assets('fonts/MonoSpace.ttf'), boxSize * 0.15),
52
+ }
53
+ const handleTap = useCallback((event: TapGestureHandlerStateChangeEvent) => {
54
+ if (event.nativeEvent.state !== 5) return;
55
+ // Adjust tap coordinates for scale
56
+ const x = event.nativeEvent.x / scale;
57
+ const y = event.nativeEvent.y / scale;
58
+ for (let i = 0; i < data.length; i++) {
59
+ const [sx, sy, seatName, status] = data[i];
60
+ const xSize = (boxSize / 2) + (sx * boxSize);
61
+ const ySize = (boxSize / 2) + (sy * boxSize);
62
+
63
+ if (x >= xSize && x <= xSize + boxSize && y >= ySize && y <= ySize + boxSize) {
64
+ if (status == 0) {
65
+ setSelectedIdx(i);
66
+ } /* else {
67
+ setSelectedIdx(null);
68
+ } */
69
+ return;
70
+ }
71
+
72
+ }
73
+ }, [data, boxSize, scale]);
74
+
75
+ useEffect(() => {
76
+ new LibCurl("v3/event_seat", {
77
+ event_id: 398,
78
+ price_id: 1922,
79
+ ondate: "0000-00-00"
80
+ }, (res, msg) => {
81
+ setBoundingBox(res.metadata.bounding_box)
82
+ setData(res.layout.split(';').map((item: any) => item.split(',')).map(([x, y, seatName, status]: any) => [Number(x), Number(y), seatName, Number(status)]))
83
+ })
84
+
85
+ loadDataSeatmapBooked()
86
+
87
+ }, [])
88
+
89
+ function updateIndexByRes(data: any, res: any) {
90
+ const resArr = res.split(",").map((item: any) => item.trim()); // biar aman dari spasi
91
+ return data.map((row: any) => {
92
+ if (resArr.includes(row[2])) {
93
+ return [row[0], row[1], row[2], 3];
94
+ }
95
+ return row;
96
+ });
97
+ }
98
+
99
+ function loadDataSeatmapBooked() {
100
+ new LibCurl("v3/event_seat_booked", {
101
+ event_id: 398,
102
+ price_id: 1922,
103
+ ondate: "0000-00-00"
104
+ }, (res, msg) => {
105
+ let updated = updateIndexByRes(getData(), res)
106
+ setData(updated)
107
+ // esp.log({ updated, res });
108
+ }, (err) => {
109
+ esp.log({ err });
110
+ })
111
+
112
+ }
113
+
114
+ return (
115
+ <View key={scale} style={{ flex: 1, backgroundColor: LibStyle.colorBgGrey }} >
116
+ <EventHeader title={esp.lang("event/seat_map", "header_title")} />
117
+ <View style={{ flex: 1 }}>
118
+ <View style={{ marginBottom: 5, }}>
119
+ <ScrollView style={{ padding: 10, paddingLeft: 0, }} horizontal>
120
+ <UseMap
121
+ data={getLegends()}
122
+ renderItem={(item) => (
123
+ <View style={{ flexDirection: 'row', alignItems: 'center', marginLeft: 15, marginRight: 5 }} >
124
+ <View style={{ height: 20, width: 20, borderRadius: 2, borderWidth: 0.5, backgroundColor: item[0], marginRight: 8 }} />
125
+ <LibTextstyle textStyle='caption1' text={item[1]} />
126
+ </View>
127
+ )}
128
+ />
129
+ </ScrollView>
130
+ </View>
131
+ <View style={{ height: 40, marginLeft: 20, marginRight: 20, backgroundColor: LibStyle.colorPrimary, marginBottom: 10, borderRadius: 2, justifyContent: 'center', alignItems: 'center' }} >
132
+ <LibTextstyle textStyle='body' style={{ color: 'white', fontWeight: 'bold' }} >{stage || esp.lang("event/seat_map", "front")}</LibTextstyle>
133
+ </View>
134
+
135
+ <ScrollView horizontal >
136
+ <ScrollView >
137
+ <TapGestureHandler onHandlerStateChange={handleTap}>
138
+ <View>
139
+ <Canvas
140
+ style={{
141
+ width: width * scale,
142
+ height: height * scale,
143
+ padding: 10,
144
+ backgroundColor: LibStyle.colorBgGrey,
145
+
146
+ }}>
147
+ {
148
+ data.map(([x, y, name, status], i) => {
149
+ const color = selectedIdx == i ? "#8EF67B" : getColorByStatus(status)
150
+ const xSize = (boxSize / 2) + (x * boxSize)
151
+ const ySize = (boxSize / 2) + (y * boxSize)
152
+ return (
153
+ <Group key={i}>
154
+ <RoundedRect
155
+ x={xSize - 1}
156
+ r={(boxSize + 2) * 0.1}
157
+ y={ySize - 1}
158
+ width={boxSize + 2}
159
+ transform={[{ scale }]}
160
+ height={boxSize + 2}
161
+ color={"#999"} />
162
+ <RoundedRect
163
+ x={xSize}
164
+ r={boxSize * 0.1}
165
+ y={ySize}
166
+ width={boxSize}
167
+ transform={[{ scale }]}
168
+ height={boxSize}
169
+ color={color} />
170
+ {name && size[name.length] && (
171
+ <Text
172
+ x={(xSize) + boxSize * (5 - name.length) * 0.1}
173
+ y={(ySize) + boxSize * 0.60}
174
+ color={"#020202"}
175
+ text={name}
176
+ transform={[{ scale }]}
177
+ font={size[name.length]} />
178
+ )}
179
+ </Group>
180
+ )
181
+ })
182
+ }
183
+ </Canvas>
184
+ </View>
185
+ </TapGestureHandler>
186
+ </ScrollView>
187
+ </ScrollView>
188
+ <View style={{ flexDirection: 'row', marginHorizontal: 12, height: 40, borderColor: '#060606', borderWidth: 1, borderRadius: 5, alignItems: 'center' }} >
189
+ <Pressable onPress={() => setScale((x) => x - 0.3)} style={{ height: 40, width: 40, alignItems: 'center', justifyContent: 'center' }} >
190
+ <LibIcon.SimpleLineIcons name='magnifier-remove' />
191
+ </Pressable>
192
+ <Pressable onPress={() => setScale((x) => x + 0.3)} style={{ height: 40, width: 40, alignItems: 'center', justifyContent: 'center' }} >
193
+ <LibIcon.SimpleLineIcons name='magnifier-add' />
194
+ </Pressable>
195
+ <View style={{ height: 40, width: 1, backgroundColor: '#060606', marginRight: 12 }} />
196
+ {/* <Text style={{}} >{esp.lang("event/seat_map", "selected", String(data.filter((x) => x == -1).length), qty)}</Text> */}
197
+ <LibTextstyle textStyle='callout'>{"Kursi terpilih"}</LibTextstyle>
198
+ </View>
199
+ <EventButton
200
+ backgroundColor={LibStyle.colorPrimary}
201
+ testID={"save_btn"}
202
+ style={{ margin: 7 }}
203
+ label={esp.lang("event/seat_map", "save")}
204
+ onPress={() => { }}
205
+ />
206
+ </View>
207
+ </View>
208
+ )
209
+ }
210
+
211
+ function getLegends() {
212
+ const colors: any = [
213
+ ["#fff", esp.lang("event/seat_map", "available"), 0],
214
+ ["#8EF67B", esp.lang("event/seat_map", "chosen"), "-1"],
215
+ ["#2EBBE8", esp.lang("event/seat_map", "reserved"), 3],
216
+ ["#6C432C", esp.lang("event/seat_map", "chosen_by"), 7],
217
+ ["#f1f2f3", esp.lang("event/seat_map", "way"), 5],
218
+ ["#9FA1A4", esp.lang("event/seat_map", "not_sold"), 1],
219
+ ["#6B71E6", esp.lang("event/seat_map", "seat_hold"), 2],
220
+ ["#FF4866", esp.lang("event/seat_map", "wall"), 6],
221
+ ["#FFA601", esp.lang("event/seat_map", "other_type"), 4],
222
+ ["purple", esp.lang("event/seat_map", "stage"), 8]
223
+ ]
224
+ return colors
225
+ }
226
+
227
+ function getColorByStatus(statuses: number) {
228
+ const colors: any = {
229
+ 8: 'purple',
230
+ 0: '#fff',
231
+ 1: "#9FA1A4",
232
+ 2: "#6B71E6",
233
+ 3: "#2EBBE8",
234
+ 4: "#FFA601",
235
+ 5: "#fff",
236
+ 6: "#FF4866",
237
+ 7: "#6C432C"
238
+ }
239
+ return colors[statuses]
240
+ }
@@ -303,14 +303,17 @@ export default function m(props: EventTicket_listProps): any {
303
303
  if (selectedTicket?.config && selectedTicket?.config?.seat_autopick == 1) {
304
304
  checkAddition(dataPost)
305
305
  } else {
306
- LibNavigation.navigateForResult('event/seat_map', {
306
+ LibNavigation.navigateForResult(esp.isDebug("") ? 'event/seat_map_new' : 'event/seat_map', {
307
307
  url: 'event_seat',
308
308
  dataTicket: dataPost,
309
309
  }).then((value) => {
310
- dataPost.row_id = value.row_id
311
- dataPost.column_id = value.column_id
312
- dataPost.seat_name = value.seat_name
313
-
310
+ if (esp.isDebug("")) {
311
+ dataPost.seat_label = value.seat_label
312
+ } else {
313
+ dataPost.row_id = value.row_id
314
+ dataPost.column_id = value.column_id
315
+ dataPost.seat_name = value.seat_name
316
+ }
314
317
  checkAddition(dataPost)
315
318
  })
316
319
  }
@@ -160,7 +160,7 @@ export default function m(props: EventTicket_list2Props): any {
160
160
  const [ticketSeat, resetTicketSeat] = taskSeat((item: any) => new Promise((next) => {
161
161
  if (item.use_seat == 1) {
162
162
  if (item.adjacent_seats == 0) {
163
- LibNavigation.navigateForResult('event/seat_map', {
163
+ LibNavigation.navigateForResult(esp.isDebug("") ? 'event/seat_map_new' : 'event/seat_map', {
164
164
  url: 'event_seat',
165
165
  dataTicket: {
166
166
  ...dataEvent,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "esoftplay-event",
3
- "version": "0.0.1-c",
3
+ "version": "0.0.1-d",
4
4
  "description": "event module on esoftplay framework",
5
5
  "main": "index.js",
6
6
  "scripts": {