esoftplay-event 0.0.2-e → 0.0.2-g

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/config.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "fonts": {
3
- "mono": "mono.ttf",
4
3
  "Arial": "Arial.ttf",
5
4
  "ArialBold": "ArialBold.ttf",
6
5
  "SFProText": "SFProText.ttf",
6
+ "mono": "mono.ttf",
7
7
  "MonoSpace": "MonoSpace.ttf",
8
8
  "DecoNumbers": "DecoNumbers.ttf",
9
9
  "digital": "digital.ttf"
@@ -64,6 +64,8 @@ export default function m(props: EventAdditional_inputProps): any {
64
64
 
65
65
  const [newData, setNewData] = useSafeState()
66
66
  const [, setIdx, getIdx] = useLazyState<number>()
67
+ const inputRefs = useRef<React.RefObject<EventInput_rectangle>[]>([]);
68
+
67
69
 
68
70
  useEffect(() => {
69
71
  if (Object.keys(itemAddition).length > 0) {
@@ -75,6 +77,12 @@ export default function m(props: EventAdditional_inputProps): any {
75
77
  return () => LibNavigation.cancelBackResult(LibNavigation.getResultKey(props))
76
78
  }, [])
77
79
 
80
+ useEffect(() => {
81
+ if (data?.additions?.length) {
82
+ inputRefs.current = data.additions.map((_, i: number) => inputRefs.current[i] || React.createRef<EventInput_rectangle>());
83
+ }
84
+ }, [data?.additions]);
85
+
78
86
  function save() {
79
87
  let stillEmpty1 = newData?.additions?.filter((item: any) => item.is_required == 1).filter((it: any) => (it.value?.length == 0 && !it.subvalue)).length > 0
80
88
  if (stillEmpty1) {
@@ -85,6 +93,7 @@ export default function m(props: EventAdditional_inputProps): any {
85
93
  }
86
94
  }
87
95
 
96
+
88
97
  function renderCatNew(item: any, i: number) {
89
98
  let values = newData?.additions?.[i]?.value
90
99
  let display_values = newData?.additions?.[i]?.display_value
@@ -109,11 +118,17 @@ export default function m(props: EventAdditional_inputProps): any {
109
118
  {
110
119
  item.type == 1 && // text field
111
120
  <EventInput_rectangle
121
+ ref={inputRefs.current[i]}
112
122
  placeholder={item.question}
123
+ returnKeyType='next'
113
124
  placeholderTextColor='#c9c9c9'
114
125
  style={{ borderRadius: 5, borderColor: '#c9c9c9' }}
115
126
  defaultValue={newData?.additions?.[i]?.value?.[0]}
116
127
  inputStyle={{ marginLeft: 0 }}
128
+ onSubmitEditing={() => {
129
+ const nextInput = inputRefs.current[i + 1];
130
+ nextInput?.current?.focus();
131
+ }}
117
132
  onChangeText={(text) => {
118
133
  let t = text?.length == 0 ? [] : [text]
119
134
  let updateValue = LibObject.set(newData, t)('additions', i, 'value')
package/event/artist.tsx CHANGED
@@ -100,7 +100,9 @@ export default function m(props: BigbangArtistProps): any {
100
100
  if (item.book_available == 1) {
101
101
  if (isInPricingQueueConfig(item.event_id)) {
102
102
  LibNavigation.navigateForResult('event/queue_pricing', { event_id: item?.event_id, autoPass: false }).then((v) => {
103
- EventCountdownProperty.countdownTime.set(moment().add(EventFirebase_socketProperty.eventQueueConfig.get(item?.event_id).time, 'seconds').localeFormat('YYYY-MM-DD HH:mm:ss'))
103
+ const expTimestamp = Date.now() + (Number(EventFirebase_socketProperty.eventQueueConfig.get(item?.event_id).time) * 1000);
104
+ EventCountdownProperty.countdownTime.set(expTimestamp)
105
+
104
106
  if (item?.config?.hasOwnProperty('multiprice') && item?.config?.multiprice == 1) {
105
107
  LibNavigation.navigate('event/artist_detail_multi', {
106
108
  data: newItem,
@@ -443,6 +443,14 @@ export default function m(props: EventArtist_detailProps): any {
443
443
 
444
444
  }} key={i} style={{ overflow: 'hidden', margin: 15, marginBottom: 5, backgroundColor: '#fff', borderRadius: 10, ...LibStyle.elevation(2), borderWidth: 1, borderColor: selTic ? LibStyle.colorBlue : LibStyle.colorBgGrey }}>
445
445
  <View style={{ padding: 10, backgroundColor: '#f1f2f3', borderTopLeftRadius: 10, borderTopRightRadius: 10 }}>
446
+ {
447
+ item?.hasOwnProperty('label') && (item?.label != "" && item?.label != null) &&
448
+ <View style={applyStyle({ flexDirection: 'row' })}>
449
+ <View style={applyStyle({ alignContent: 'center', alignItems: 'center', justifyContent: 'center', borderWidth: 1, backgroundColor: item?.label_color, borderColor: item?.label_color, borderRadius: 3, padding: 2, paddingHorizontal: 5, opacity: 1 })}>
450
+ <Text allowFontScaling={false} style={{ fontSize: 10, fontStyle: "normal", letterSpacing: 0.5, color: EventOrder_itemProperty.textColor(item?.label_color), fontWeight: 'bold' }}>{item?.label}</Text>
451
+ </View>
452
+ </View>
453
+ }
446
454
  <View style={{ alignContent: 'center', alignItems: 'center', flexDirection: 'row', justifyContent: 'space-between', }}>
447
455
  <EventHtmltext allowFontScaling={false} style={{ opacity: textOpacity, fontWeight: 'bold' }}>{item.type}</EventHtmltext>
448
456
  {
@@ -6,6 +6,7 @@ import { EventConfigProperty } from 'esoftplay/cache/event/config/import';
6
6
  import { EventCountdownProperty } from 'esoftplay/cache/event/countdown/import';
7
7
  import { EventHeader } from 'esoftplay/cache/event/header/import';
8
8
  import { EventIndexProperty } from 'esoftplay/cache/event/index/import';
9
+ import { EventOrder_itemProperty } from 'esoftplay/cache/event/order_item/import';
9
10
  import { EventShare } from 'esoftplay/cache/event/share/import';
10
11
  import { LibCarrousel } from 'esoftplay/cache/lib/carrousel/import';
11
12
  import { LibCurl } from 'esoftplay/cache/lib/curl/import';
@@ -476,6 +477,14 @@ export default function m(props: EventArtist_detail_multiProps): any {
476
477
  return (
477
478
  <View key={i} style={{ overflow: 'hidden', margin: 15, marginBottom: 5, backgroundColor: '#fff', borderRadius: 10, ...LibStyle.elevation(2), borderWidth: 1, borderColor: /* selTic ? LibStyle.colorBlue : */ LibStyle.colorBgGrey }}>
478
479
  <View style={{ padding: 10, backgroundColor: '#f1f2f3', borderTopLeftRadius: 10, borderTopRightRadius: 10 }}>
480
+ {
481
+ item?.hasOwnProperty('label') && (item?.label != "" && item?.label != null) &&
482
+ <View style={applyStyle({ flexDirection: 'row' })}>
483
+ <View style={applyStyle({ alignContent: 'center', alignItems: 'center', justifyContent: 'center', borderWidth: 1, backgroundColor: item?.label_color, borderColor: item?.label_color, borderRadius: 3, padding: 2, paddingHorizontal: 5, opacity: 1 })}>
484
+ <Text allowFontScaling={false} style={{ fontSize: 10, fontStyle: "normal", letterSpacing: 0.5, color: EventOrder_itemProperty.textColor(item?.label_color), fontWeight: 'bold' }}>{item?.label}</Text>
485
+ </View>
486
+ </View>
487
+ }
479
488
  <View style={{ alignContent: 'center', alignItems: 'center', flexDirection: 'row', justifyContent: 'space-between', }}>
480
489
  <Text allowFontScaling={false} style={{ opacity: textOpacity, fontWeight: 'bold' }}>{item.type}</Text>
481
490
  {
@@ -86,7 +86,8 @@ export default function m(props: EventArtistv2Props): any {
86
86
  // autoPass: false,
87
87
  // });
88
88
  // }
89
- // EventCountdownProperty.countdownTime.set(moment().add(EventFirebase_socketProperty.eventQueueConfig.get(item?.event_id).time, 'seconds').localeFormat('YYYY-MM-DD HH:mm:ss'));
89
+ // const expTimestamp = Date.now() + (Number(EventFirebase_socketProperty.eventQueueConfig.get(item?.event_id).time) * 1000);
90
+ // EventCountdownProperty.countdownTime.set(expTimestamp)
90
91
  LibNavigation.navigate(
91
92
  item?.config?.multiprice == 1
92
93
  ? 'event/artist_detail_multi'
@@ -120,7 +121,7 @@ export default function m(props: EventArtistv2Props): any {
120
121
  } else if (item?.images?.length == 1) {
121
122
  return (
122
123
  <TouchableOpacity key={i} onPress={handlePress} >
123
- <LibPicture style={{opacity: isNotAvailable ? 0.3 : 1, height: sliderHeight, width: width, resizeMode: 'cover', backgroundColor: "#f1f2f3" }} source={{ uri: item.images[0] }} />
124
+ <LibPicture style={{ opacity: isNotAvailable ? 0.3 : 1, height: sliderHeight, width: width, resizeMode: 'cover', backgroundColor: "#f1f2f3" }} source={{ uri: item.images[0] }} />
124
125
  </TouchableOpacity>
125
126
  )
126
127
  } else {
@@ -16,26 +16,32 @@ export interface EventButton_order_detailProps {
16
16
  title: string
17
17
  info?: string
18
18
  color: any,
19
- icon: any
19
+ icon: any,
20
+ disable?: boolean
21
+ status_message?: string
20
22
  }
21
23
  export default function m(props: EventButton_order_detailProps): any {
22
24
  return (
23
- <TouchableOpacity onPress={props.onPress}>
25
+ <TouchableOpacity onPress={props.onPress} activeOpacity={props.disable == true ? 1 : 0}>
24
26
  <View style={{ borderWidth: 1, borderColor: '#ccc', margin: 15, borderRadius: 7, marginBottom: 0, overflow: 'hidden', flexDirection: 'row' }}>
25
27
  <LibGradient
26
- colors={[props.color, props.color, "#f1f2f3",]}
28
+ colors={props.disable ? [LibStyle.colorBgGrey, LibStyle.colorBgGrey, "#f1f2f3"] : [props.color, props.color, "#f1f2f3",]}
27
29
  direction='left-to-right'
28
30
  style={{ margin: 3, borderRadius: 5, padding: 7, flex: 4, alignContent: 'center', justifyContent: 'center' }}
29
31
  >
30
- <Text allowFontScaling={false} numberOfLines={2} ellipsizeMode='tail' style={{ color: EventOrder_itemProperty.textColor(props?.color), fontSize: 16, fontWeight: 'bold' }}>{props.title}</Text>
32
+ <Text allowFontScaling={false} numberOfLines={2} ellipsizeMode='tail' style={{ color: props?.disable ? "#adb5bd" : EventOrder_itemProperty.textColor(props?.color), fontSize: 16, fontWeight: 'bold' }}>{props.title}</Text>
31
33
  {
32
34
  props.info != "" &&
33
- <Text allowFontScaling={false} numberOfLines={2} ellipsizeMode='tail' style={{ color: EventOrder_itemProperty.textColor(props?.color), fontSize: 12, fontWeight: 'normal' }}>{props?.info}</Text>
35
+ <Text allowFontScaling={false} ellipsizeMode='tail' style={{ color: props?.disable ? "#adb5bd" : EventOrder_itemProperty.textColor(props?.color), fontSize: 12, fontWeight: 'normal' }}>{props?.info}</Text>
36
+ }
37
+ {
38
+ props.status_message && props.status_message != "" &&
39
+ <Text allowFontScaling={false} ellipsizeMode='tail' style={{ color: LibStyle.colorRed, fontSize: 12, fontWeight: 'normal' }}>{props?.status_message}</Text>
34
40
  }
35
41
  </LibGradient>
36
- <View style={{ flex: 1, margin: 3, borderRadius: 5, ...LibStyle.elevation(2), backgroundColor: props.color, justifyContent: 'center', alignContent: 'center', alignItems: 'center' }}>
42
+ <View style={{ flex: 1, margin: 3, borderRadius: 5, ...LibStyle.elevation(2), backgroundColor: props.disable ? LibStyle.colorBgGrey : props.color, justifyContent: 'center', alignContent: 'center', alignItems: 'center' }}>
37
43
  {/* <LibIcon name={"dice-multiple"} size={40} color={EventOrder_itemProperty.textColor(props.color)} style={{ opacity: 1 }} /> */}
38
- <LibIcon name={props.icon} size={35} color={EventOrder_itemProperty.textColor(props.color)} style={{ opacity: 1 }} />
44
+ <LibIcon name={props.icon} size={35} color={props?.disable ? "#adb5bd" : EventOrder_itemProperty.textColor(props?.color)} style={{ opacity: 1 }} />
39
45
  </View>
40
46
  </View>
41
47
  </TouchableOpacity>
@@ -1,6 +1,6 @@
1
1
  // withHooks
2
2
 
3
- import { EventCountdown_base } from 'esoftplay/cache/event/countdown_base/import';
3
+ import { EventCountdown_timestamp } from 'esoftplay/cache/event/countdown_timestamp/import';
4
4
  import { EventFirebase_socket } from 'esoftplay/cache/event/firebase_socket/import';
5
5
  import { EventQueue_pricingProperty } from 'esoftplay/cache/event/queue_pricing/import';
6
6
  import { LibNavigation } from 'esoftplay/cache/lib/navigation/import';
@@ -54,7 +54,7 @@ export default function m(props: EventCountdownProps): any {
54
54
  else
55
55
  return (
56
56
  <Animated.View pointerEvents='none' style={[{ position: 'absolute', alignItems: 'center', justifyContent: 'center', top: LibStyle.STATUSBAR_HEIGHT + 61, padding: 1, backgroundColor: LibUtils.hexToRgba(LibStyle.colorGreen, 1), width: '100%' }, animated]} >
57
- <EventCountdown_base
57
+ <EventCountdown_timestamp
58
58
  onExpired={() => {
59
59
  const routeNames = UserRoutes.state()?.get()?.routes?.map?.((x: any) => x.name)
60
60
  if (routeNames.includes("event/artist"))
@@ -65,7 +65,7 @@ export default function m(props: EventCountdownProps): any {
65
65
  LibNavigation.backToRoot()
66
66
  countdownTime.reset()
67
67
  }}
68
- expired={timer}
68
+ expiredTimestamp={timer}
69
69
  style={{ color: "#fff" }} />
70
70
  </Animated.View>
71
71
  )
@@ -0,0 +1,106 @@
1
+ // withHooks
2
+ // noPage
3
+
4
+ import esp from 'esoftplay/esp';
5
+ import React, { useEffect, useRef } from 'react';
6
+ import { TextInput, View } from 'react-native';
7
+
8
+ export interface EventCountdown_timestampProps {
9
+ expiredTimestamp: number;
10
+ expiredText?: string;
11
+ style?: any;
12
+ containerStyle?: any;
13
+ onlyDay?: boolean;
14
+ onExpired?: () => void;
15
+ hideTimeUnit?: boolean;
16
+ showDayUnit?: boolean;
17
+ }
18
+
19
+ const fixSingleNumber = (n: number) => (n < 10 ? "0" + n : n);
20
+
21
+ export default function CountdownTimestamp(props: EventCountdown_timestampProps) {
22
+ const ref = useRef<TextInput>(null)
23
+ let timmerRef = useRef<any>(undefined)
24
+
25
+ useEffect(() => {
26
+ countDown()
27
+ return () => {
28
+ clearTimeout(timmerRef.current)
29
+ timmerRef.current = undefined
30
+ }
31
+ }, [])
32
+
33
+ function countDown(): any {
34
+ let expired = false
35
+ function loop() {
36
+ const labels = [esp.lang("market/countdown", "day"), esp.lang("market/countdown", "hour"), esp.lang("market/countdown", "minutes"), esp.lang("market/countdown", "second")]
37
+
38
+ const expiredTimestamp = props.expiredTimestamp
39
+ const now = Date.now();
40
+ const diffMs = expiredTimestamp - now;
41
+
42
+ if (diffMs <= 0) {
43
+ expired = true;
44
+ props.onExpired?.();
45
+ ref.current?.setNativeProps({
46
+ text: props.expiredText || esp.lang('market/countdown', 'expired'),
47
+ });
48
+ return;
49
+ }
50
+
51
+ const totalSeconds = Math.floor(diffMs / 1000);
52
+ const days = Math.floor(totalSeconds / 86400);
53
+ const hours = Math.floor((totalSeconds % 86400) / 3600);
54
+ const minutes = Math.floor((totalSeconds % 3600) / 60);
55
+ const seconds = totalSeconds % 60;
56
+
57
+ const parts = [
58
+ days,
59
+ fixSingleNumber(hours),
60
+ fixSingleNumber(minutes),
61
+ fixSingleNumber(seconds),
62
+ ];
63
+
64
+ if (parts[0] != 0 && props.onlyDay) {
65
+ ref.current?.setNativeProps({
66
+ text: parts[0] + esp.lang('market/countdown', 'days'),
67
+ });
68
+ } else if (parts[0] == 0) {
69
+ const filteredParts = [...parts];
70
+ while (filteredParts.length > 1 && (filteredParts[0] === 0 || filteredParts[0] === "00")) {
71
+ filteredParts.splice(0, 1);
72
+ }
73
+
74
+ const filtered = filteredParts.map((d, i) =>
75
+ `${d}${props?.hideTimeUnit ? '' : ' ' + labels[parts.length - filteredParts.length + i]}`
76
+ );
77
+
78
+ ref.current?.setNativeProps({ text: filtered.join(' : ') });
79
+ } else if (props?.showDayUnit && props?.hideTimeUnit) {
80
+ const data = parts.map(
81
+ (d, i) => d + (i === 0 ? ' ' + labels[0] + ' ' : '')
82
+ );
83
+
84
+ const first = data[0];
85
+ ref.current?.setNativeProps({
86
+ text: first + ' ' + data.slice(1).join(' : '),
87
+ });
88
+ } else {
89
+ const filtered = parts.map(
90
+ (d, i) => `${d}${props?.hideTimeUnit ? '' : ' ' + labels[i]}`
91
+ );
92
+ ref.current?.setNativeProps({ text: filtered.join(' : ') });
93
+ }
94
+
95
+ if (!expired) timmerRef.current = setTimeout(loop, 1000);
96
+
97
+ };
98
+ loop()
99
+ }
100
+
101
+ return (
102
+ <View style={props.containerStyle} >
103
+ <TextInput ref={ref} editable={false} allowFontScaling={false} style={props.style} />
104
+ </View>
105
+ )
106
+ }
@@ -106,6 +106,7 @@ export default function m(props: EventOrder_detailProps): any {
106
106
  const url = LibNavigation.getArgs(props, 'url')
107
107
  const [result, setResult] = useSafeState<any>(EventIndexProperty?.stateTicketCache()?.get()?.filter?.((x: any) => x.url?.replace?.('?id=', '/') == url?.replace?.('?id=', '/'))?.[0]?.detail)
108
108
  const [tickets, setTickets] = useSafeState(result?.detail_ticket?.tickets ?? [])
109
+ const [dataAddons, setDataAddons] = useSafeState()
109
110
  const useIndividualQr = result?.config?.use_individual_qr_ticket
110
111
 
111
112
  const dataTickets = tickets?.filter?.((x: ItemTiket) => x?.email == user?.email && x?.ticket_code != '')
@@ -165,6 +166,17 @@ export default function m(props: EventOrder_detailProps): any {
165
166
  }
166
167
  )
167
168
 
169
+ // addons list
170
+ if (res?.hasOwnProperty('url_addons') && res?.url_addons != "") {
171
+ new LibCurl(res?.url_addons, null,
172
+ (resss: any, msg: string) => {
173
+ setDataAddons(resss)
174
+ }, (err: any) => {
175
+ esp.log(err, "res url_addons");
176
+ }
177
+ )
178
+ }
179
+
168
180
  }, (error: any) => {
169
181
  const transformedUrl = url?.includes("?id=") ? url?.replace(/\?id=/, '/') : url
170
182
  const urlArr = transformedUrl?.split("/")
@@ -259,7 +271,7 @@ export default function m(props: EventOrder_detailProps): any {
259
271
  currency: res?.currency,
260
272
  }
261
273
  },
262
- qty: result?.qty
274
+ qty: res?.qty
263
275
  }
264
276
  let fee_platform = {
265
277
  fee_platform_amount: res?.fee_platform?.fee_platform_amount,
@@ -270,17 +282,37 @@ export default function m(props: EventOrder_detailProps): any {
270
282
  let order_type = EventConfigProperty.state().get()?.order_type?.ticket
271
283
  let addons_id = id
272
284
  let booking_id_ref = result?.id
273
- LibNavigation.navigate('payment/ticket', {
274
- order_type: order_type,
275
- tax: tax,
276
- fee_platform: fee_platform,
277
- dataBookingEvent: dataBookingEvent,
278
- show_fee_percentage,
279
- addons_id,
280
- booking_id_ref
281
- })
285
+
286
+ if (res?.hasOwnProperty('alert') && res?.alert != "") {
287
+ LibDialog.warningConfirm("Informasi", res?.alert, "Lanjutkan", () => {
288
+ LibNavigation.navigate('payment/ticket', {
289
+ order_type: order_type,
290
+ tax: tax,
291
+ fee_platform: fee_platform,
292
+ dataBookingEvent: dataBookingEvent,
293
+ show_fee_percentage,
294
+ addons_id,
295
+ booking_id_ref
296
+ })
297
+ }, "Kembali", () => {
298
+
299
+ })
300
+ } else {
301
+ LibNavigation.navigate('payment/ticket', {
302
+ order_type: order_type,
303
+ tax: tax,
304
+ fee_platform: fee_platform,
305
+ dataBookingEvent: dataBookingEvent,
306
+ show_fee_percentage,
307
+ addons_id,
308
+ booking_id_ref
309
+ })
310
+ }
311
+
312
+
282
313
  }, (err: any) => {
283
314
  LibProgress.hide()
315
+ LibDialog.warning("Oops", err?.message)
284
316
  esp.log({ err });
285
317
  }, 1)
286
318
  }
@@ -444,16 +476,18 @@ export default function m(props: EventOrder_detailProps): any {
444
476
  </View>
445
477
  {/* </View> */}
446
478
  <UseCondition if={result?.show_ticket_status == 1 && result?.status == 1 || result?.status == 3 || result?.status == 6}>
447
- <Text allowFontScaling={false} style={{ fontSize: 12, fontWeight: "normal", fontStyle: "normal", letterSpacing: 0, marginBottom: 12, color: "#484848" }}>
448
- {
449
- result?.qty_used == 0 ? esp.lang("event/order", "have_not_been_used")
450
- :
451
- result.kind_detail?.everyday_pass == 1 ?
452
- "(" + result?.qty_used_today + " " + esp.lang("event/order_detail", "used_today") + ")"
479
+ <View style={{ flex: 1, marginRight: LibStyle.width / 4 }}>
480
+ <Text allowFontScaling={false} style={{ fontSize: 12, fontWeight: "normal", fontStyle: "normal", letterSpacing: 0, marginBottom: 12, color: "#484848" }}>
481
+ {
482
+ result?.qty_used == 0 ? esp.lang("event/order", "have_not_been_used")
453
483
  :
454
- "(" + result?.qty_used + " " + esp.lang("event/order_detail", "used") + ")"
455
- }
456
- </Text>
484
+ result.kind_detail?.everyday_pass == 1 ?
485
+ "(" + result?.qty_used_today + " " + esp.lang("event/order_detail", "used_today") + ")"
486
+ :
487
+ "(" + result?.qty_used + " " + esp.lang("event/order_detail", "used") + ")"
488
+ }
489
+ </Text>
490
+ </View>
457
491
  </UseCondition>
458
492
  {
459
493
  result?.qty_shared > 0 &&
@@ -576,10 +610,12 @@ export default function m(props: EventOrder_detailProps): any {
576
610
 
577
611
  {/* tombol add on */}
578
612
  {
579
- result?.addons?.length > 0 && result?.addons?.map((item: any, i: number) => {
613
+ dataAddons?.length > 0 && dataAddons?.map((item: any, i: number) => {
580
614
  if (item?.hasOwnProperty("group_id")) {
581
615
  return (
582
616
  <EventButton_order_detail
617
+ disable={item?.hasOwnProperty('status') && item.status == 0 ? true : false}
618
+ status_message={item?.status_message}
583
619
  key={i}
584
620
  color={result?.color}
585
621
  onPress={() => {
@@ -591,12 +627,14 @@ export default function m(props: EventOrder_detailProps): any {
591
627
  }}
592
628
  icon={'chevron-down'}
593
629
  title={item.group_title}
594
- info={""}
630
+ info={item.info}
595
631
  />
596
632
  )
597
633
  } else if (item?.hasOwnProperty('list')) {
598
634
  return (
599
635
  <EventButton_order_detail
636
+ disable={item?.hasOwnProperty('status') && item.status == 0 ? true : false}
637
+ status_message={item?.status_message}
600
638
  key={i}
601
639
  color={result?.color}
602
640
  onPress={() => {
@@ -608,16 +646,20 @@ export default function m(props: EventOrder_detailProps): any {
608
646
  }}
609
647
  icon={'chevron-down'}
610
648
  title={item.title}
611
- info={""}
649
+ info={item.info}
612
650
  />
613
651
  )
614
652
  } else {
615
653
  return (
616
654
  <EventButton_order_detail
655
+ disable={item?.hasOwnProperty('status') && item.status == 0 ? true : false}
656
+ status_message={item?.status_message}
617
657
  key={i}
618
658
  color={result?.color}
619
659
  onPress={() => {
620
- loadDataAddons(item?.addons_id, item?.url)
660
+ if (item?.hasOwnProperty('status') && item?.status == 1) {
661
+ loadDataAddons(item?.addons_id, item?.url)
662
+ }
621
663
  }}
622
664
  icon={'plus-circle-outline'}
623
665
  title={item.title}
@@ -904,10 +946,14 @@ export default function m(props: EventOrder_detailProps): any {
904
946
  getGroupAddon()?.list?.length > 0 && getGroupAddon()?.list?.map((item: any, i: number) => {
905
947
  return (
906
948
  <EventButton_order_detail
949
+ disable={item?.hasOwnProperty('status') && item.status == 0 ? true : false}
950
+ status_message={item?.status_message}
907
951
  key={i}
908
952
  color={result?.color}
909
953
  onPress={() => {
910
- loadDataAddons(getGroupAddon()?.addons_id, item?.url)
954
+ if (item?.hasOwnProperty('status') && item?.status == 1) {
955
+ loadDataAddons(getGroupAddon()?.addons_id, item?.url)
956
+ }
911
957
  }}
912
958
  icon={'plus-circle-outline'}
913
959
  title={getGroupAddon()?.title + " " + LibUtils.moment(item.ondate).format("DD MMM YYYY")}
@@ -921,10 +967,14 @@ export default function m(props: EventOrder_detailProps): any {
921
967
  getGroupAddon()?.addons?.length > 0 && getGroupAddon()?.addons?.map((item: any, i: number) => {
922
968
  return (
923
969
  <EventButton_order_detail
970
+ disable={item?.hasOwnProperty('status') && item.status == 0 ? true : false}
971
+ status_message={item?.status_message}
924
972
  key={i}
925
973
  color={result?.color}
926
974
  onPress={() => {
927
- loadDataAddons(item?.addons_id, item?.url)
975
+ if (item?.hasOwnProperty('status') && item?.status == 1) {
976
+ loadDataAddons(item?.addons_id, item?.url)
977
+ }
928
978
  }}
929
979
  icon={'plus-circle-outline'}
930
980
  title={item.title}
@@ -122,10 +122,11 @@ export default function m(props: EventOrder_detail_upgradeProps): any {
122
122
  }
123
123
  }} key={i} style={{
124
124
  ...LibStyle.elevation(2), marginHorizontal: 15, marginTop: 2.5, marginBottom: 10, borderRadius: 10,
125
- backgroundColor: item.status == 0 ? LibStyle.colorBgGrey : selectedTicket?.selected_ticket?.id == item.id ? LibStyle.colorGreen : "#fff", padding: 10, alignContent: 'center', alignItems: 'center', justifyContent: 'center'
125
+ backgroundColor: item.status != 1 ? LibStyle.colorBgGrey : selectedTicket?.selected_ticket?.id == item.id ? LibStyle.colorGreen : "#fff", padding: 10, alignContent: 'center', alignItems: 'center', justifyContent: 'center'
126
126
  }}>
127
- <EventHtmltext allowFontScaling={false} style={{ marginHorizontal: 5, fontSize: 16, color: item.status == 0 ? "#c9c9c9" : selectedTicket?.selected_ticket?.id == item.id ? "#fff" : "#000", textAlign: 'center', fontWeight: 'bold' }} numberOfLines={2} ellipsizeMode={'tail'}>{item?.price_name_to}</EventHtmltext>
128
- <Text allowFontScaling={false} style={{ fontSize: 14, fontWeight: 'bold', marginTop: 5, color: item.status == 0 ? "#c9c9c9" : selectedTicket?.selected_ticket?.id == item.id ? "#fff" : "#000" }}>{"+ " + LibUtils.money(Number(dataTicket?.qty_upgrade) * Number(item?.amount), item?.currency)}</Text>
127
+ {/* <Text allowFontScaling={false} style={{ color: LibStyle.colorRed }} >{item?.message_error}</Text> */}
128
+ <EventHtmltext allowFontScaling={false} style={{ marginHorizontal: 5, fontSize: 16, color: item.status != 1 ? "#c9c9c9" : selectedTicket?.selected_ticket?.id == item.id ? "#fff" : "#000", textAlign: 'center', fontWeight: 'bold' }} numberOfLines={2} ellipsizeMode={'tail'}>{item?.price_name_to}</EventHtmltext>
129
+ <Text allowFontScaling={false} style={{ fontSize: 14, fontWeight: 'bold', marginTop: 5, color: item.status != 1 ? "#c9c9c9" : selectedTicket?.selected_ticket?.id == item.id ? "#fff" : "#000" }}>{"+ " + LibUtils.money(Number(dataTicket?.qty_upgrade) * Number(item?.amount), item?.currency)}</Text>
129
130
 
130
131
  {
131
132
  item.info &&
@@ -56,7 +56,7 @@ export default function m(props: EventOrder_detail_upgrade_paymentProps): any {
56
56
  }
57
57
 
58
58
  if (selectedTicket?.selected_ticket?.use_seat == 1) {
59
- post.seat_label = selectedTicket?.seat_label.join('|')
59
+ post.seat_label = selectedTicket?.seat_label?.join('|')
60
60
  }
61
61
 
62
62
  if (selectedTicket?.selected_ticket?.seat_autopick == 1) {
@@ -19,15 +19,15 @@ import moment from 'esoftplay/moment';
19
19
  import { applyStyle } from 'esoftplay';
20
20
  import { EventConfigProperty } from 'esoftplay/cache/event/config/import';
21
21
  import { EventCountdownProperty } from 'esoftplay/cache/event/countdown/import';
22
- import { EventCountdown_base } from 'esoftplay/cache/event/countdown_base/import';
23
22
  import { EventCountdown_event } from 'esoftplay/cache/event/countdown_event/import';
23
+ import { EventCountdown_timestamp } from 'esoftplay/cache/event/countdown_timestamp/import';
24
24
  import { EventFirebase_socket, EventFirebase_socketProperty } from 'esoftplay/cache/event/firebase_socket/import';
25
25
  import { EventHtmltext } from 'esoftplay/cache/event/htmltext/import';
26
26
  import { EventLoading_pageProperty } from 'esoftplay/cache/event/loading_page/import';
27
+ import { EventOrder_itemProperty } from 'esoftplay/cache/event/order_item/import';
27
28
  import { LibEffect } from 'esoftplay/cache/lib/effect/import';
28
29
  import { LibProgress } from 'esoftplay/cache/lib/progress/import';
29
30
  import { UseDeeplinkProperty } from 'esoftplay/cache/use/deeplink/import';
30
- import { UserClass } from 'esoftplay/cache/user/class/import';
31
31
  import esp from 'esoftplay/esp';
32
32
  import useLazyState from 'esoftplay/lazy';
33
33
  import useSafeState from 'esoftplay/state';
@@ -155,8 +155,10 @@ export default function m(props: EventTicket_listProps): any {
155
155
  useEffect(() => {
156
156
  EventConfigProperty.curlConfig('v2/config_order_type')
157
157
  const { event_id } = EventQueue_pricingProperty.state().get()
158
- if (isInPricingQueueConfig(event_id))
159
- EventCountdownProperty.countdownTime.set(moment().add(EventFirebase_socketProperty.eventQueueConfig.get(event_id).time, 'seconds').localeFormat('YYYY-MM-DD HH:mm:ss'))
158
+ if (isInPricingQueueConfig(event_id)) {
159
+ const expTimestamp = Date.now() + (Number(EventFirebase_socketProperty.eventQueueConfig.get(event_id).time) * 1000);
160
+ EventCountdownProperty.countdownTime.set(expTimestamp)
161
+ }
160
162
  // loadData()
161
163
  getCheckCounter()
162
164
  return () => {
@@ -577,11 +579,11 @@ export default function m(props: EventTicket_listProps): any {
577
579
  <LibEffect deps={[]}>
578
580
  <View style={{ backgroundColor: LibStyle.colorGreen, margin: 16, borderRadius: 5, padding: 10, ...LibStyle.elevation(2) }} >
579
581
  <LibTextstyle text={esp.lang("event/ticket_list", "select_ticket")} textStyle='caption1' style={{ color: 'white' }} />
580
- <EventCountdown_base
582
+ <EventCountdown_timestamp
581
583
  onExpired={() => {
582
584
  LibNavigation.navigate("event/detail")
583
585
  }}
584
- expired={timer}
586
+ expiredTimestamp={timer}
585
587
  style={{ color: "#fff", fontWeight: 'bold' }} />
586
588
  </View>
587
589
  </LibEffect>
@@ -613,10 +615,10 @@ export default function m(props: EventTicket_listProps): any {
613
615
  }} key={i} style={{ overflow: 'hidden', margin: 15, marginBottom: 5, backgroundColor: '#fff', borderRadius: 5, borderWidth: 1.5, borderColor: selTic ? LibStyle.colorBlue : LibStyle.colorBgGrey }}>
614
616
  <View style={{ padding: 10, backgroundColor: '#f1f2f3', borderTopLeftRadius: 5, borderTopRightRadius: 5 }}>
615
617
  {
616
- esp.isDebug("") && UserClass.state().get()?.email == "bagus@fisip.net" &&
618
+ item?.hasOwnProperty('label') && (item?.label != "" && item?.label != null) &&
617
619
  <View style={applyStyle({ flexDirection: 'row' })}>
618
- <View style={applyStyle({ alignContent: 'center', alignItems: 'center', justifyContent: 'center', borderWidth: 1, backgroundColor: LibStyle.colorGreen, borderColor: "#4cd964", borderRadius: 5, padding: 2, paddingHorizontal: 5, opacity: 1 })}>
619
- <Text allowFontScaling={false} style={{ fontSize: 10, fontStyle: "normal", letterSpacing: 0.5, color: '#fff', fontWeight: 'bold' }}>Disini kah boy</Text>
620
+ <View style={applyStyle({ alignContent: 'center', alignItems: 'center', justifyContent: 'center', borderWidth: 1, backgroundColor: item?.label_color, borderColor: item?.label_color, borderRadius: 3, padding: 2, paddingHorizontal: 5, opacity: 1 })}>
621
+ <Text allowFontScaling={false} style={{ fontSize: 10, fontStyle: "normal", letterSpacing: 0.5, color: EventOrder_itemProperty.textColor(item?.label_color), fontWeight: 'bold' }}>{item?.label}</Text>
620
622
  </View>
621
623
  </View>
622
624
  }
@@ -21,8 +21,8 @@ import { useEffect, useRef } from 'react';
21
21
  import { EventAlert } from 'esoftplay/cache/event/alert/import';
22
22
  import { EventConfigProperty } from 'esoftplay/cache/event/config/import';
23
23
  import { EventCountdownProperty } from 'esoftplay/cache/event/countdown/import';
24
- import { EventCountdown_base } from 'esoftplay/cache/event/countdown_base/import';
25
24
  import { EventCountdown_event } from 'esoftplay/cache/event/countdown_event/import';
25
+ import { EventCountdown_timestamp } from 'esoftplay/cache/event/countdown_timestamp/import';
26
26
  import { EventFirebase_socket, EventFirebase_socketProperty } from 'esoftplay/cache/event/firebase_socket/import';
27
27
  import { EventHtmltext } from 'esoftplay/cache/event/htmltext/import';
28
28
  import { EventLoading_pageProperty } from 'esoftplay/cache/event/loading_page/import';
@@ -271,8 +271,10 @@ export default function m(props: EventTicket_list2Props): any {
271
271
  EventConfigProperty.curlConfig('v2/config_order_type')
272
272
  const { event_id } = EventQueue_pricingProperty.state().get()
273
273
  loadData()
274
- if (isInPricingQueueConfig(event_id))
275
- EventCountdownProperty.countdownTime.set(moment().add(EventFirebase_socketProperty.eventQueueConfig.get(event_id).time, 'seconds').localeFormat('YYYY-MM-DD HH:mm:ss'))
274
+ if (isInPricingQueueConfig(event_id)) {
275
+ const expTimestamp = Date.now() + (Number(EventFirebase_socketProperty.eventQueueConfig.get(event_id).time) * 1000);
276
+ EventCountdownProperty.countdownTime.set(expTimestamp)
277
+ }
276
278
  getCheckCounter()
277
279
  return () => {
278
280
  clearTimeout(refTimeout.current)
@@ -656,11 +658,11 @@ export default function m(props: EventTicket_list2Props): any {
656
658
  isInPricingQueueConfig(availableResult?.id) && isPass ?
657
659
  <View style={{ backgroundColor: LibStyle.colorGreen, margin: 16, borderRadius: 5, padding: 10, ...LibStyle.elevation(2) }} >
658
660
  <LibTextstyle text={esp.lang("event/ticket_list", "select_ticket")} textStyle='caption1' style={{ color: 'white' }} />
659
- <EventCountdown_base
661
+ <EventCountdown_timestamp
660
662
  onExpired={() => {
661
663
  LibNavigation.back(1)
662
664
  }}
663
- expired={timer}
665
+ expiredTimestamp={timer}
664
666
  style={{ color: "#fff", fontWeight: 'bold' }} />
665
667
  </View>
666
668
  : null
@@ -697,6 +699,14 @@ export default function m(props: EventTicket_list2Props): any {
697
699
 
698
700
  }} key={i} style={{ overflow: 'hidden', margin: 15, marginBottom: 5, marginTop: 10, backgroundColor: '#fff', borderRadius: 10, ...LibStyle.elevation(2), borderWidth: 1, borderColor: item.selected == 1 ? LibStyle.colorBlue : LibStyle.colorBgGrey }}>
699
701
  <View style={{ padding: 10, backgroundColor: '#f1f2f3', borderTopLeftRadius: 10, borderTopRightRadius: 10 }}>
702
+ {
703
+ item?.hasOwnProperty('label') && (item?.label != "" && item?.label != null) &&
704
+ <View style={applyStyle({ flexDirection: 'row' })}>
705
+ <View style={applyStyle({ alignContent: 'center', alignItems: 'center', justifyContent: 'center', borderWidth: 1, backgroundColor: item?.label_color, borderColor: item?.label_color, borderRadius: 3, padding: 2, paddingHorizontal: 5, opacity: 1 })}>
706
+ <Text allowFontScaling={false} style={{ fontSize: 10, fontStyle: "normal", letterSpacing: 0.5, color: EventOrder_itemProperty.textColor(item?.label_color), fontWeight: 'bold' }}>{item?.label}</Text>
707
+ </View>
708
+ </View>
709
+ }
700
710
  <View style={{ alignContent: 'center', alignItems: 'center', flexDirection: 'row', justifyContent: 'space-between', }}>
701
711
  <View>
702
712
  <EventHtmltext allowFontScaling={false} style={{ opacity: textOpacity, fontWeight: 'bold' }}>{item.type}
@@ -136,7 +136,7 @@ export default function m(props: EventTms_idcardProps): any {
136
136
  <LibPicture source={result?.event?.image_idcard == "" ? esp.assets('white_idcard.png') : { uri: result?.event?.image_idcard }} style={{ width: width, height: height, resizeMode: 'contain' }} />
137
137
  <View style={{ position: 'absolute' }}>
138
138
  <LibPicture source={{ uri: selectedTicket?.user_image != '' ? decodeURIComponent(selectedTicket?.user_image) : 'https://www.w3schools.com/howto/img_avatar.png' }} style={{ marginBottom: photoMarginBot, marginTop: marginTop, height: photoHeight, width: photoWidth, alignSelf: 'center', resizeMode: 'cover', }} />
139
- <View style={{ padding: 10, marginTop: -10 }} >
139
+ <View style={{ padding: 10, marginTop: 5 }} >
140
140
  {/* view nama */}
141
141
  <View style={{ flexDirection: 'row' }} >
142
142
  <Text allowFontScaling={false} style={{ fontSize: 16, fontWeight: "bold", fontStyle: "normal", lineHeight: 22, letterSpacing: 0, color: "#4a4a4a", flex: 3 }} >{esp.lang("event/tms_idcard", "name")}</Text>
@@ -3,7 +3,18 @@ import { EventHeader } from 'esoftplay/cache/event/header/import';
3
3
  import { LibIcon } from 'esoftplay/cache/lib/icon/import';
4
4
  import { LibStyle } from 'esoftplay/cache/lib/style/import';
5
5
  import esp from 'esoftplay/esp';
6
+ import { useRef } from 'react';
6
7
 
8
+ import { applyStyle } from 'esoftplay';
9
+ import { EventButton } from 'esoftplay/cache/event/button/import';
10
+ import { EventOrder_status } from 'esoftplay/cache/event/order_status/import';
11
+ import { EventSection_menu } from 'esoftplay/cache/event/section_menu/import';
12
+ import { LibNavigation } from 'esoftplay/cache/lib/navigation/import';
13
+ import { LibScroll } from 'esoftplay/cache/lib/scroll/import';
14
+ import { LibSlidingup } from 'esoftplay/cache/lib/slidingup/import';
15
+ import { LibTextstyle } from 'esoftplay/cache/lib/textstyle/import';
16
+ import { LibUtils } from 'esoftplay/cache/lib/utils/import';
17
+ import useSafeState from 'esoftplay/state';
7
18
  import React from 'react';
8
19
  import { Pressable, ScrollView, Text, View } from 'react-native';
9
20
 
@@ -15,13 +26,39 @@ export interface EventToken_orderProps {
15
26
 
16
27
  }
17
28
  export default function m(props: EventToken_orderProps): any {
29
+
30
+ const allStatus = EventOrder_status()
31
+ const statusCode = LibNavigation.getArgs(props, 'status', esp.isDebug("filter") ? '0,1,2,3,4,5,6,7,10' : '1')
32
+ const [status, setStatus] = useSafeState(statusCode)
33
+ const [code, setCode] = useSafeState(statusCode)
34
+ const [selectedDate, setSelectedDate] = useSafeState({ date_start: '', date_end: '', id: 1, title: esp.lang("event/order", "all_date") })
35
+ const [selectedDateRange, setSelectedDateRange] = useSafeState({ date_start: LibUtils.moment().localeFormat("YYYY-MM-DD"), date_end: LibUtils.moment().localeFormat("YYYY-MM-DD") })
36
+
37
+ const statusRef = useRef<LibSlidingup>(null)
38
+
39
+
18
40
  return (
19
41
  <View style={{ flex: 1, backgroundColor: LibStyle.colorBgGrey }}>
20
42
  <EventHeader title='Riwayar Transaksi Token' />
43
+ <View style={{ minHeight: 50, }} >
44
+ <LibScroll
45
+ initialNumToRender={20}
46
+ horizontal
47
+ >
48
+ <View style={{ width: 10 }} />
49
+ <Pressable
50
+ onPress={() => { statusRef.current?.show() }}
51
+ style={applyStyle({ height: 30, marginVertical: 10, marginRight: 10, borderRadius: 12, backgroundColor: 'white', borderColor: '#ccc', borderWidth: 1, paddingHorizontal: 10, justifyContent: 'center', flexDirection: 'row', alignItems: 'center' })} >
52
+ <LibTextstyle textStyle='footnote' text={allStatus[allStatus.findIndex((x) => String(x.code) == status)]?.text || esp.lang("event/order", "all_statis")} style={applyStyle({ fontSize: 11, color: "#4E4E4E", marginRight: 5 })} />
53
+ <LibIcon name='chevron-down' style={applyStyle({ color: "#4E4E4E" })} />
54
+ </Pressable>
55
+ </LibScroll>
56
+ <EventSection_menu size='line' />
57
+ </View>
21
58
  <ScrollView>
22
59
  <Pressable onPress={() => {
23
60
 
24
- }} style={{ padding: 7, margin: 15, backgroundColor: '#fff', marginBottom: 0, borderRadius: 5, borderWidth: 1, borderColor: LibStyle.colorPrimary, flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
61
+ }} style={{ padding: 7, margin: 15, marginTop: 10, backgroundColor: '#fff', marginBottom: 0, borderRadius: 5, borderWidth: 1, borderColor: LibStyle.colorPrimary, flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
25
62
  <Text allowFontScaling={false} style={{ marginLeft: 8 }}>{esp.lang("event/order", "wawit")}</Text>
26
63
  <View style={{ flexDirection: 'row', alignItems: 'center' }}>
27
64
  {/* {
@@ -34,6 +71,33 @@ export default function m(props: EventToken_orderProps): any {
34
71
  </View>
35
72
  </Pressable>
36
73
  </ScrollView>
74
+ <LibSlidingup ref={statusRef} onChangeShow={(s) => { if (!s) setCode(status) }} >
75
+ <View style={applyStyle({ backgroundColor: 'white', paddingHorizontal: 17, borderTopLeftRadius: 10, borderTopRightRadius: 10, maxHeight: LibStyle.height * 0.9 })}>
76
+ <View style={applyStyle({ flexDirection: 'row', alignItems: 'center', marginTop: 15 })}>
77
+ <Pressable onPress={() => { statusRef.current?.hide() }} style={applyStyle({ marginRight: 10 })} >
78
+ <LibIcon name='close' />
79
+ </Pressable>
80
+ <LibTextstyle textStyle='footnote' text={esp.lang("event/order", "Transaction_Status")} style={applyStyle({ fontWeight: 'bold', fontSize: 14, color: "#4E4E4E" })} />
81
+ </View>
82
+ <ScrollView>
83
+ <Pressable onPress={() => { setCode('0,1,2,3,4,5,6,7,10') }} style={applyStyle({ flexDirection: 'row', alignItems: 'center', borderBottomWidth: 1, borderBottomColor: '#e6e6e6', paddingVertical: 12 })}>
84
+ <LibTextstyle textStyle='footnote' text={esp.lang("event/order", "All_Transaction_Status")} style={applyStyle({ flex: 1, fontWeight: 'bold', fontSize: 10, color: "#4E4E4E" })} />
85
+ <LibIcon.Ionicons name={code == '0,1,2,3,4,5,6,7,10' ? 'radio-button-on' : 'radio-button-off'} color={code == '0,1,2,3,4,5,6,7,10' ? LibStyle.colorPrimary : '#4E4E4E'} />
86
+ </Pressable>
87
+ {
88
+ allStatus?.filter((item: any) => item.publish == 1).map((it: any, i: number) => {
89
+ return (
90
+ <Pressable key={i} onPress={() => setCode(it.code)} style={applyStyle({ flexDirection: 'row', alignItems: 'center', borderBottomWidth: 1, borderBottomColor: '#e6e6e6', paddingVertical: 12 })}>
91
+ <LibTextstyle textStyle='footnote' text={it.text} style={applyStyle({ flex: 1, fontWeight: 'bold', fontSize: 10, color: "#4E4E4E" })} />
92
+ <LibIcon.Ionicons name={it.code == code ? 'radio-button-on' : 'radio-button-off'} color={it.code == code ? LibStyle.colorPrimary : '#4E4E4E'} />
93
+ </Pressable>
94
+ )
95
+ })
96
+ }
97
+ </ScrollView>
98
+ <EventButton label={esp.lang("event/order", "apply")} style={applyStyle({ fontSize: 14, marginVertical: 15 })} backgroundColor={LibStyle.colorPrimary} onPress={() => { setStatus(code); statusRef.current?.hide() }} />
99
+ </View>
100
+ </LibSlidingup>
37
101
  </View>
38
102
  )
39
103
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "esoftplay-event",
3
- "version": "0.0.2-e",
3
+ "version": "0.0.2-g",
4
4
  "description": "event module on esoftplay framework",
5
5
  "main": "index.js",
6
6
  "scripts": {