esoftplay-event 0.0.1-c → 0.0.1-e

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 (44) hide show
  1. package/config.json +1 -1
  2. package/event/artist.tsx +3 -6
  3. package/event/detail.tsx +0 -44
  4. package/event/order.tsx +2 -1
  5. package/event/order_detail.tsx +2 -4
  6. package/event/order_detail_upgrade_payment.tsx +13 -7
  7. package/event/order_detail_waiting.tsx +21 -9
  8. package/event/order_share_to.tsx +2 -2
  9. package/event/scan_item.tsx +2 -2
  10. package/event/seat_map_new.tsx +313 -0
  11. package/event/test.tsx +240 -155
  12. package/event/ticket_list.tsx +8 -5
  13. package/event/ticket_list2.tsx +1 -1
  14. package/event/tms_check_ticket_result.tsx +5 -5
  15. package/event/tms_in_failed.tsx +1 -1
  16. package/id.json +5 -4
  17. package/package.json +1 -1
  18. package/event/entrance.tsx +0 -215
  19. package/event/entrance_again.tsx +0 -199
  20. package/event/entrance_failed.tsx +0 -190
  21. package/event/entrance_idcard.tsx +0 -199
  22. package/event/entrance_list.tsx +0 -264
  23. package/event/entrance_list_item.tsx +0 -88
  24. package/event/entrance_log.tsx +0 -130
  25. package/event/entrance_success.tsx +0 -153
  26. package/event/entrance_warning.tsx +0 -91
  27. package/event/exit.tsx +0 -91
  28. package/event/exit_failed.tsx +0 -135
  29. package/event/exit_list.tsx +0 -118
  30. package/event/exit_log.tsx +0 -130
  31. package/event/exit_success.tsx +0 -143
  32. package/event/exit_temporary.tsx +0 -226
  33. package/event/hall_in.tsx +0 -148
  34. package/event/hall_in_failed.tsx +0 -270
  35. package/event/hall_in_list.tsx +0 -222
  36. package/event/hall_in_log.tsx +0 -134
  37. package/event/hall_in_success.tsx +0 -132
  38. package/event/hall_out.tsx +0 -143
  39. package/event/hall_out_failed.tsx +0 -133
  40. package/event/hall_out_list.tsx +0 -215
  41. package/event/hall_out_log.tsx +0 -133
  42. package/event/hall_out_success.tsx +0 -130
  43. package/event/log.tsx +0 -433
  44. package/event/seat_map_test.tsx +0 -401
package/config.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "fonts": {
3
+ "mono": "mono.ttf",
3
4
  "Arial": "Arial.ttf",
4
5
  "ArialBold": "ArialBold.ttf",
5
6
  "SFProText": "SFProText.ttf",
6
- "mono": "mono.ttf",
7
7
  "MonoSpace": "MonoSpace.ttf",
8
8
  "DecoNumbers": "DecoNumbers.ttf",
9
9
  "digital": "digital.ttf"
package/event/artist.tsx CHANGED
@@ -36,15 +36,12 @@ export default function m(props: BigbangArtistProps): any {
36
36
 
37
37
  const { title, has_addition } = LibNavigation.getArgsAll(props)
38
38
  const url = LibNavigation.getArgs(props, 'url', 'event_artist')
39
- const regex = /(\d+)$/;
40
- const match = url.match(regex);
41
- const [event_id] = useSafeState(match?.[1])
42
39
 
43
40
  function loadData(): void {
44
41
  /* get detail event untuk dapat config antrian */
45
42
  new LibCurl(url, null,
46
43
  (res) => {
47
- new LibCurl(res?.[0]?.url_event || `event_detail/${event_id}`, null, (res) => {
44
+ new LibCurl(res?.[0]?.url_event || `event_detail/${res?.[0]?.event_id}`, null, (res) => {
48
45
  setResultEvent(res)
49
46
  if (res?.id) {
50
47
  EventFirebase_socketProperty.eventIdQueue.set(res?.id)
@@ -95,8 +92,8 @@ export default function m(props: BigbangArtistProps): any {
95
92
  }
96
93
  if (item.book_available == 1) {
97
94
  if (isInPricingQueueConfig(item.event_id)) {
98
- LibNavigation.navigateForResult('event/queue_pricing', { event_id: event_id, autoPass: false }).then((v) => {
99
- EventCountdownProperty.countdownTime.set(moment().add(EventFirebase_socketProperty.eventQueueConfig.get(event_id).time, 'seconds').localeFormat('YYYY-MM-DD HH:mm:ss'))
95
+ LibNavigation.navigateForResult('event/queue_pricing', { event_id: item?.event_id, autoPass: false }).then((v) => {
96
+ EventCountdownProperty.countdownTime.set(moment().add(EventFirebase_socketProperty.eventQueueConfig.get(item?.event_id).time, 'seconds').localeFormat('YYYY-MM-DD HH:mm:ss'))
100
97
  if (item?.config?.hasOwnProperty('multiprice') && item?.config?.multiprice == 1) {
101
98
  LibNavigation.navigate('event/artist_detail_multi', {
102
99
  data: newItem,
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,8 @@ 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
+ // 7 pembayaran kadaluarsa
132
+ LibNavigation.navigate(status == "7" ? 'event/order_detail_waiting' : 'event/order_detail', { url: item.url })
132
133
  }} />
133
134
  )
134
135
  }
@@ -133,8 +133,6 @@ 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);
137
-
138
136
  new LibCurl(res?.url_coupon, null, (ress: any) => {
139
137
  setCoupons(ress)
140
138
  }, (error: any) => {
@@ -470,7 +468,7 @@ export default function m(props: EventOrder_detailProps): any {
470
468
 
471
469
  <EventAlert
472
470
  color="#FFC523"
473
- msg={esp.lang("event/order_detail", "not_allowed_ss")}
471
+ msg={esp.lang("event/order_detail", "not_allowed_ss", esp.appjson().expo.name)}
474
472
  useIcon
475
473
  style={{ marginBottom: 0, margin: 15 }}
476
474
  />
@@ -725,7 +723,7 @@ export default function m(props: EventOrder_detailProps): any {
725
723
  <View style={{ padding: 5, }}>
726
724
  <EventButton label={Number(result.is_shareable) ? /*share_ticket*/esp.lang("event/order_detail", "share_ticket") : esp.lang("event/order_detail", "shared")} onPress={() => {
727
725
  if (Number(result.is_shareable)) {
728
- LibDialog.confirm(esp.lang("event/order_detail", "share_title"), esp.lang("event/order_detail", "share_msg"), esp.lang("event/order_detail", "share_ok"), () => {
726
+ LibDialog.confirm(esp.lang("event/order_detail", "share_title"), esp.lang("event/order_detail", "share_msg", esp.appjson().expo.name), esp.lang("event/order_detail", "share_ok"), () => {
729
727
  LibNavigation.navigate('event/order_share_to', { url: url })
730
728
  }, esp.lang("event/order_detail", "share_no"), () => {
731
729
 
@@ -15,7 +15,7 @@ import { LibStyle } from "esoftplay/cache/lib/style/import";
15
15
  import { LibTextstyle } from 'esoftplay/cache/lib/textstyle/import';
16
16
  import esp from "esoftplay/esp";
17
17
  import useSafeState from "esoftplay/state";
18
- import { ScrollView, Text, View } from "react-native";
18
+ import { Linking, ScrollView, Text, View } from "react-native";
19
19
 
20
20
 
21
21
 
@@ -68,17 +68,14 @@ export default function m(props: EventOrder_detail_upgrade_paymentProps): any {
68
68
  }
69
69
  LibProgress.show(esp.lang("event/order_detail_upgrade_payment", "confirm_wait"))
70
70
  new LibCurl('event_order_detail_upgrade_checkout', post, (res, msg) => {
71
- esp.log({ post });
72
71
  LibProgress.hide()
73
72
  LibNavigation.reset()
74
- if (selectedPayment?.payment_id == 2) /* bbo pay */ {
75
- LibToastProperty.show(msg)
76
- LibNavigation.navigate('event/order_detail', { url: res?.url })
77
- } else if (selectedPayment?.payment_id == 3)/* cc */ {
73
+ if (res?.hasOwnProperty('url_web') && res?.url_web != null) {
78
74
  LibNavigation.navigateForResult('payment/cc_web', {
79
75
  ...res,
80
76
  statusSuccess: [1]
81
77
  }).then((res) => {
78
+ LibNavigation.backToRoot()
82
79
  LibNavigation.push('user/profile')
83
80
  if (res?.hasOwnProperty('params_error') || res?.hasOwnProperty('failed')) {
84
81
  LibNavigation.push('event/order_waiting')
@@ -87,9 +84,18 @@ export default function m(props: EventOrder_detail_upgrade_paymentProps): any {
87
84
  LibNavigation.push('event/order')
88
85
  }
89
86
  })
87
+ } else if (res?.hasOwnProperty('url_mobile') && res?.url_mobile != null) {
88
+ Linking.openURL(res?.url_mobile)
89
+ LibNavigation.push('event/order_detail_waiting', { url: res?.url })
90
90
  } else {
91
- LibNavigation.navigate('event/order_detail_waiting', { url: res?.url })
91
+ if (res?.url?.includes("waiting")) {
92
+ LibNavigation.push('event/order_waiting')
93
+ }
94
+ LibNavigation.push(res?.url?.includes("waiting") ? 'event/order_detail_waiting' : 'event/order_detail', {
95
+ url: res.url,
96
+ })
92
97
  }
98
+
93
99
  }, (err) => {
94
100
  LibProgress.hide()
95
101
  LibDialog.warning(esp.lang("event/order_detail_upgrade_payment", "oops"), err?.message)
@@ -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={() => {
@@ -98,7 +98,7 @@ export default function m(props: EventOrder_share_toProps): any {
98
98
 
99
99
  return (
100
100
  <LibKeyboard_avoid style={{ flex: 1, backgroundColor: '#fff' }}>
101
- <EventHeader title={esp.lang("event/order_share_to", "title_share_ticket_to")} />
101
+ <EventHeader title={esp.lang("event/order_share_to", "title_share_ticket_to", esp.appjson().expo.name)} />
102
102
  <ScrollView showsVerticalScrollIndicator={false} >
103
103
  <TouchableOpacity onPress={() => {
104
104
  LibNavigation.navigate('component/scanner', {
@@ -112,7 +112,7 @@ export default function m(props: EventOrder_share_toProps): any {
112
112
  <LibPicture source={esp.assets('icons/ic_barcode_white.png')} style={{ height: 250, width: 250 }} />
113
113
  <Text allowFontScaling={false} style={{ fontFamily: "Arial", fontSize: 14, fontWeight: "bold", fontStyle: "normal", letterSpacing: 0, textAlign: "center", marginTop: 10, color: '#fff' }}>{esp.lang("event/order_share_to", "click_here")}</Text>
114
114
  <Text allowFontScaling={false} style={{ color: '#fff', fontFamily: "Arial", fontSize: 14, fontWeight: "bold", fontStyle: "normal", letterSpacing: 0, textAlign: "center", marginTop: 6 }}>{esp.lang("event/order_share_to", "scan_qrcode")}</Text>
115
- <Text allowFontScaling={false} style={{ color: '#fff', fontFamily: "Arial", fontSize: 12, fontWeight: "normal", fontStyle: "normal", letterSpacing: 0, textAlign: "center", marginTop: 5 }}>{esp.lang("event/order_share_to", "in_member_bbo_page")}</Text>
115
+ <Text allowFontScaling={false} style={{ color: '#fff', fontFamily: "Arial", fontSize: 12, fontWeight: "normal", fontStyle: "normal", letterSpacing: 0, textAlign: "center", marginTop: 5 }}>{esp.lang("event/order_share_to", "in_member_bbo_page", esp.appjson().expo.name)}</Text>
116
116
  </View>
117
117
  </TouchableOpacity>
118
118
  <Text allowFontScaling={false} style={{ opacity: 0.6, fontFamily: "Arial", fontSize: 12, fontWeight: "normal", fontStyle: "normal", letterSpacing: 0, textAlign: "center", marginTop: 17 }}>{esp.lang("event/order_share_to", "or")}</Text>
@@ -49,11 +49,11 @@ export default function m(props: EventScan_itemProps): any {
49
49
  <View style={{}}>
50
50
  {
51
51
  props?.item?.hall_scanned && props?.item?.hall_scanned != "0000-00-00 00:00:00" &&
52
- <Text allowFontScaling={false} ellipsizeMode={'tail'} numberOfLines={2} style={applyStyle({ color: "#c9c9c9", marginBottom: 4, fontSize: 14, letterSpacing: 1.5 })}>{esp.lang("event/scan_item", "scan_on") + LibUtils.moment(props?.item?.hall_scanned).serverFormat("DD MMMM YYYY H:m:s")}</Text>
52
+ <Text allowFontScaling={false} ellipsizeMode={'tail'} numberOfLines={2} style={applyStyle({ color: "#c9c9c9", marginBottom: 4, fontSize: 14, letterSpacing: 1.5 })}>{esp.lang("event/scan_item", "scan_on") + LibUtils.moment(props?.item?.hall_scanned).serverFormat("DD MMMM YYYY H:m:s ", props?.item?.timezone) + props.item?.timezone_locale || ""}</Text>
53
53
  }
54
54
  {
55
55
  !Array.isArray(props?.item?.scanned_detail) && props?.item?.scanned_detail?.scanned != "" && props?.item?.scanned_detail?.scanned != "0000-00-00 00:00:00" &&
56
- <Text allowFontScaling={false} ellipsizeMode={'tail'} numberOfLines={2} style={applyStyle({ color: LibStyle.colorRed, marginBottom: 4, fontSize: 14, letterSpacing: 1.5 })}>{esp.lang("event/scan_item", "scan_on") + LibUtils.moment(props?.item?.hall_scanned).serverFormat("DD MMMM YYYY H:m:s")}</Text>
56
+ <Text allowFontScaling={false} ellipsizeMode={'tail'} numberOfLines={2} style={applyStyle({ color: LibStyle.colorRed, marginBottom: 4, fontSize: 14, letterSpacing: 1.5 })}>{esp.lang("event/scan_item", "scan_on") + LibUtils.moment(props?.item?.scanned_detail?.scanned).serverFormat("DD MMMM YYYY H:m:s ", props?.item?.timezone) + props.item?.timezone_locale || ""}</Text>
57
57
  }
58
58
  {
59
59
  props.item?.status == 1 &&
@@ -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
+ }