related-ui-components 1.3.3 → 1.3.5

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 (188) hide show
  1. package/lib/commonjs/app.js +39 -20
  2. package/lib/commonjs/app.js.map +1 -1
  3. package/lib/commonjs/components/DateRangePicker/DateRangePicker.js +358 -0
  4. package/lib/commonjs/components/DateRangePicker/DateRangePicker.js.map +1 -0
  5. package/lib/commonjs/components/DateRangePicker/index.js +4 -0
  6. package/lib/commonjs/components/DateRangePicker/index.js.map +1 -0
  7. package/lib/commonjs/components/Filters/Filters.js +1 -1
  8. package/lib/commonjs/components/Filters/Filters.js.map +1 -1
  9. package/lib/commonjs/components/Input/Input.js +2 -2
  10. package/lib/commonjs/components/Input/Input.js.map +1 -1
  11. package/lib/commonjs/components/NumericStepper/NumericStepper.js +103 -0
  12. package/lib/commonjs/components/NumericStepper/NumericStepper.js.map +1 -0
  13. package/lib/commonjs/components/NumericStepper/index.js +29 -0
  14. package/lib/commonjs/components/NumericStepper/index.js.map +1 -0
  15. package/lib/commonjs/components/SelectAmount/SelectAmount.js +189 -0
  16. package/lib/commonjs/components/SelectAmount/SelectAmount.js.map +1 -0
  17. package/lib/commonjs/components/SelectAmount/index.js +4 -0
  18. package/lib/commonjs/components/SelectAmount/index.js.map +1 -0
  19. package/lib/commonjs/components/Suggestions/SuggestionList.js +98 -0
  20. package/lib/commonjs/components/Suggestions/SuggestionList.js.map +1 -0
  21. package/lib/commonjs/components/TravelBooking/CarRentalForm.js +370 -0
  22. package/lib/commonjs/components/TravelBooking/CarRentalForm.js.map +1 -0
  23. package/lib/commonjs/components/TravelBooking/FlightForm.js +347 -0
  24. package/lib/commonjs/components/TravelBooking/FlightForm.js.map +1 -0
  25. package/lib/commonjs/components/TravelBooking/FlightSummary.js +257 -0
  26. package/lib/commonjs/components/TravelBooking/FlightSummary.js.map +1 -0
  27. package/lib/commonjs/components/TravelBooking/HotelForm.js +290 -0
  28. package/lib/commonjs/components/TravelBooking/HotelForm.js.map +1 -0
  29. package/lib/commonjs/components/TravelBooking/HotelSummary.js +246 -0
  30. package/lib/commonjs/components/TravelBooking/HotelSummary.js.map +1 -0
  31. package/lib/commonjs/components/TravelBooking/README.md +421 -0
  32. package/lib/commonjs/components/TravelBooking/SummaryBar.js +181 -0
  33. package/lib/commonjs/components/TravelBooking/SummaryBar.js.map +1 -0
  34. package/lib/commonjs/components/TravelBooking/TabSelector.js +115 -0
  35. package/lib/commonjs/components/TravelBooking/TabSelector.js.map +1 -0
  36. package/lib/commonjs/components/TravelBooking/TravelBooking.js +261 -0
  37. package/lib/commonjs/components/TravelBooking/TravelBooking.js.map +1 -0
  38. package/lib/commonjs/components/TravelBooking/index.js +22 -0
  39. package/lib/commonjs/components/TravelBooking/index.js.map +1 -0
  40. package/lib/commonjs/components/TravelBooking/types.js +15 -0
  41. package/lib/commonjs/components/TravelBooking/types.js.map +1 -0
  42. package/lib/commonjs/components/UnlockRewards/UnlockRewards.js +2 -2
  43. package/lib/commonjs/components/UnlockRewards/UnlockRewards.js.map +1 -1
  44. package/lib/commonjs/index.js +0 -5
  45. package/lib/commonjs/index.js.map +1 -1
  46. package/lib/module/app.js +43 -24
  47. package/lib/module/app.js.map +1 -1
  48. package/lib/module/components/DateRangePicker/DateRangePicker.js +350 -0
  49. package/lib/module/components/DateRangePicker/DateRangePicker.js.map +1 -0
  50. package/lib/module/components/DateRangePicker/index.js +4 -0
  51. package/lib/module/components/DateRangePicker/index.js.map +1 -0
  52. package/lib/module/components/Filters/Filters.js +1 -1
  53. package/lib/module/components/Filters/Filters.js.map +1 -1
  54. package/lib/module/components/Input/Input.js +2 -2
  55. package/lib/module/components/Input/Input.js.map +1 -1
  56. package/lib/module/components/NumericStepper/NumericStepper.js +96 -0
  57. package/lib/module/components/NumericStepper/NumericStepper.js.map +1 -0
  58. package/lib/module/components/NumericStepper/index.js +5 -0
  59. package/lib/module/components/NumericStepper/index.js.map +1 -0
  60. package/lib/module/components/SelectAmount/SelectAmount.js +184 -0
  61. package/lib/module/components/SelectAmount/SelectAmount.js.map +1 -0
  62. package/lib/module/components/SelectAmount/index.js +4 -0
  63. package/lib/module/components/SelectAmount/index.js.map +1 -0
  64. package/lib/module/components/Suggestions/SuggestionList.js +92 -0
  65. package/lib/module/components/Suggestions/SuggestionList.js.map +1 -0
  66. package/lib/module/components/TravelBooking/CarRentalForm.js +363 -0
  67. package/lib/module/components/TravelBooking/CarRentalForm.js.map +1 -0
  68. package/lib/module/components/TravelBooking/FlightForm.js +340 -0
  69. package/lib/module/components/TravelBooking/FlightForm.js.map +1 -0
  70. package/lib/module/components/TravelBooking/FlightSummary.js +254 -0
  71. package/lib/module/components/TravelBooking/FlightSummary.js.map +1 -0
  72. package/lib/module/components/TravelBooking/HotelForm.js +286 -0
  73. package/lib/module/components/TravelBooking/HotelForm.js.map +1 -0
  74. package/lib/module/components/TravelBooking/HotelSummary.js +239 -0
  75. package/lib/module/components/TravelBooking/HotelSummary.js.map +1 -0
  76. package/lib/module/components/TravelBooking/README.md +421 -0
  77. package/lib/module/components/TravelBooking/SummaryBar.js +174 -0
  78. package/lib/module/components/TravelBooking/SummaryBar.js.map +1 -0
  79. package/lib/module/components/TravelBooking/TabSelector.js +110 -0
  80. package/lib/module/components/TravelBooking/TabSelector.js.map +1 -0
  81. package/lib/module/components/TravelBooking/TravelBooking.js +243 -0
  82. package/lib/module/components/TravelBooking/TravelBooking.js.map +1 -0
  83. package/lib/module/components/TravelBooking/index.js +22 -0
  84. package/lib/module/components/TravelBooking/index.js.map +1 -0
  85. package/lib/module/components/TravelBooking/types.js +11 -0
  86. package/lib/module/components/TravelBooking/types.js.map +1 -0
  87. package/lib/module/components/UnlockRewards/UnlockRewards.js +2 -2
  88. package/lib/module/components/UnlockRewards/UnlockRewards.js.map +1 -1
  89. package/lib/module/index.js +7 -4
  90. package/lib/module/index.js.map +1 -1
  91. package/lib/typescript/commonjs/app.d.ts.map +1 -1
  92. package/lib/typescript/commonjs/components/DateRangePicker/DateRangePicker.d.ts +25 -0
  93. package/lib/typescript/commonjs/components/DateRangePicker/DateRangePicker.d.ts.map +1 -0
  94. package/lib/typescript/commonjs/components/DateRangePicker/index.d.ts +1 -0
  95. package/lib/typescript/commonjs/components/DateRangePicker/index.d.ts.map +1 -0
  96. package/lib/typescript/commonjs/components/NumericStepper/NumericStepper.d.ts +19 -0
  97. package/lib/typescript/commonjs/components/NumericStepper/NumericStepper.d.ts.map +1 -0
  98. package/lib/typescript/commonjs/components/NumericStepper/index.d.ts +3 -0
  99. package/lib/typescript/commonjs/components/NumericStepper/index.d.ts.map +1 -0
  100. package/lib/typescript/commonjs/components/SelectAmount/SelectAmount.d.ts +29 -0
  101. package/lib/typescript/commonjs/components/SelectAmount/SelectAmount.d.ts.map +1 -0
  102. package/lib/typescript/commonjs/components/SelectAmount/index.d.ts +1 -0
  103. package/lib/typescript/commonjs/components/SelectAmount/index.d.ts.map +1 -0
  104. package/lib/typescript/commonjs/components/Suggestions/SuggestionList.d.ts +14 -0
  105. package/lib/typescript/commonjs/components/Suggestions/SuggestionList.d.ts.map +1 -0
  106. package/lib/typescript/commonjs/components/TravelBooking/CarRentalForm.d.ts +58 -0
  107. package/lib/typescript/commonjs/components/TravelBooking/CarRentalForm.d.ts.map +1 -0
  108. package/lib/typescript/commonjs/components/TravelBooking/FlightForm.d.ts +57 -0
  109. package/lib/typescript/commonjs/components/TravelBooking/FlightForm.d.ts.map +1 -0
  110. package/lib/typescript/commonjs/components/TravelBooking/FlightSummary.d.ts +41 -0
  111. package/lib/typescript/commonjs/components/TravelBooking/FlightSummary.d.ts.map +1 -0
  112. package/lib/typescript/commonjs/components/TravelBooking/HotelForm.d.ts +52 -0
  113. package/lib/typescript/commonjs/components/TravelBooking/HotelForm.d.ts.map +1 -0
  114. package/lib/typescript/commonjs/components/TravelBooking/HotelSummary.d.ts +44 -0
  115. package/lib/typescript/commonjs/components/TravelBooking/HotelSummary.d.ts.map +1 -0
  116. package/lib/typescript/commonjs/components/TravelBooking/SummaryBar.d.ts +17 -0
  117. package/lib/typescript/commonjs/components/TravelBooking/SummaryBar.d.ts.map +1 -0
  118. package/lib/typescript/commonjs/components/TravelBooking/TabSelector.d.ts +17 -0
  119. package/lib/typescript/commonjs/components/TravelBooking/TabSelector.d.ts.map +1 -0
  120. package/lib/typescript/commonjs/components/TravelBooking/TravelBooking.d.ts +84 -0
  121. package/lib/typescript/commonjs/components/TravelBooking/TravelBooking.d.ts.map +1 -0
  122. package/lib/typescript/commonjs/components/TravelBooking/index.d.ts +1 -0
  123. package/lib/typescript/commonjs/components/TravelBooking/index.d.ts.map +1 -0
  124. package/lib/typescript/commonjs/components/TravelBooking/types.d.ts +26 -0
  125. package/lib/typescript/commonjs/components/TravelBooking/types.d.ts.map +1 -0
  126. package/lib/typescript/commonjs/index.d.ts +0 -1
  127. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  128. package/lib/typescript/module/app.d.ts.map +1 -1
  129. package/lib/typescript/module/components/DateRangePicker/DateRangePicker.d.ts +25 -0
  130. package/lib/typescript/module/components/DateRangePicker/DateRangePicker.d.ts.map +1 -0
  131. package/lib/typescript/module/components/DateRangePicker/index.d.ts +1 -0
  132. package/lib/typescript/module/components/DateRangePicker/index.d.ts.map +1 -0
  133. package/lib/typescript/module/components/NumericStepper/NumericStepper.d.ts +19 -0
  134. package/lib/typescript/module/components/NumericStepper/NumericStepper.d.ts.map +1 -0
  135. package/lib/typescript/module/components/NumericStepper/index.d.ts +3 -0
  136. package/lib/typescript/module/components/NumericStepper/index.d.ts.map +1 -0
  137. package/lib/typescript/module/components/SelectAmount/SelectAmount.d.ts +29 -0
  138. package/lib/typescript/module/components/SelectAmount/SelectAmount.d.ts.map +1 -0
  139. package/lib/typescript/module/components/SelectAmount/index.d.ts +1 -0
  140. package/lib/typescript/module/components/SelectAmount/index.d.ts.map +1 -0
  141. package/lib/typescript/module/components/Suggestions/SuggestionList.d.ts +14 -0
  142. package/lib/typescript/module/components/Suggestions/SuggestionList.d.ts.map +1 -0
  143. package/lib/typescript/module/components/TravelBooking/CarRentalForm.d.ts +58 -0
  144. package/lib/typescript/module/components/TravelBooking/CarRentalForm.d.ts.map +1 -0
  145. package/lib/typescript/module/components/TravelBooking/FlightForm.d.ts +57 -0
  146. package/lib/typescript/module/components/TravelBooking/FlightForm.d.ts.map +1 -0
  147. package/lib/typescript/module/components/TravelBooking/FlightSummary.d.ts +41 -0
  148. package/lib/typescript/module/components/TravelBooking/FlightSummary.d.ts.map +1 -0
  149. package/lib/typescript/module/components/TravelBooking/HotelForm.d.ts +52 -0
  150. package/lib/typescript/module/components/TravelBooking/HotelForm.d.ts.map +1 -0
  151. package/lib/typescript/module/components/TravelBooking/HotelSummary.d.ts +44 -0
  152. package/lib/typescript/module/components/TravelBooking/HotelSummary.d.ts.map +1 -0
  153. package/lib/typescript/module/components/TravelBooking/SummaryBar.d.ts +17 -0
  154. package/lib/typescript/module/components/TravelBooking/SummaryBar.d.ts.map +1 -0
  155. package/lib/typescript/module/components/TravelBooking/TabSelector.d.ts +17 -0
  156. package/lib/typescript/module/components/TravelBooking/TabSelector.d.ts.map +1 -0
  157. package/lib/typescript/module/components/TravelBooking/TravelBooking.d.ts +84 -0
  158. package/lib/typescript/module/components/TravelBooking/TravelBooking.d.ts.map +1 -0
  159. package/lib/typescript/module/components/TravelBooking/index.d.ts +1 -0
  160. package/lib/typescript/module/components/TravelBooking/index.d.ts.map +1 -0
  161. package/lib/typescript/module/components/TravelBooking/types.d.ts +26 -0
  162. package/lib/typescript/module/components/TravelBooking/types.d.ts.map +1 -0
  163. package/lib/typescript/module/index.d.ts +0 -1
  164. package/lib/typescript/module/index.d.ts.map +1 -1
  165. package/package.json +12 -8
  166. package/src/app.tsx +77 -13
  167. package/src/components/DateRangePicker/DateRangePicker.tsx +410 -0
  168. package/src/components/DateRangePicker/index.ts +2 -0
  169. package/src/components/Filters/Filters.tsx +1 -1
  170. package/src/components/Input/Input.tsx +1 -1
  171. package/src/components/NumericStepper/NumericStepper.tsx +117 -0
  172. package/src/components/NumericStepper/index.ts +2 -0
  173. package/src/components/SelectAmount/SelectAmount.tsx +217 -0
  174. package/src/components/SelectAmount/index.ts +2 -0
  175. package/src/components/Suggestions/SuggestionList.tsx +106 -0
  176. package/src/components/TravelBooking/CarRentalForm.tsx +440 -0
  177. package/src/components/TravelBooking/FlightForm.tsx +452 -0
  178. package/src/components/TravelBooking/FlightSummary.tsx +388 -0
  179. package/src/components/TravelBooking/HotelForm.tsx +365 -0
  180. package/src/components/TravelBooking/HotelSummary.tsx +340 -0
  181. package/src/components/TravelBooking/README.md +421 -0
  182. package/src/components/TravelBooking/SummaryBar.tsx +239 -0
  183. package/src/components/TravelBooking/TabSelector.tsx +158 -0
  184. package/src/components/TravelBooking/TravelBooking.tsx +407 -0
  185. package/src/components/TravelBooking/index.ts +20 -0
  186. package/src/components/TravelBooking/types.ts +28 -0
  187. package/src/components/UnlockRewards/UnlockRewards.tsx +2 -2
  188. package/src/index.ts +4 -4
package/src/app.tsx CHANGED
@@ -1,19 +1,43 @@
1
- import React, { useState } from "react";
2
- import { View, StyleSheet, Text, TouchableOpacity } from "react-native";
1
+ import React, { useRef, useState } from "react";
2
+ import {
3
+ View,
4
+ StyleSheet,
5
+ Text,
6
+ TouchableOpacity,
7
+ ScrollView,
8
+ FlatList,
9
+ Alert,
10
+ } from "react-native";
3
11
  import { Ionicons } from "@expo/vector-icons";
4
12
  import { RelatedProvider, useTheme } from "./theme";
5
13
  import {
14
+ Banner,
6
15
  Filters,
16
+ Popup,
7
17
  RedemptionOption,
8
18
  ScratchCard,
9
19
  ScratchCardContent,
10
20
  } from "./components";
11
21
  import { SafeAreaView } from "react-native-safe-area-context";
22
+ import SelectAmount from "./components/SelectAmount/SelectAmount";
23
+ import Slider from "@react-native-community/slider";
24
+ import SummaryBar from "./components/TravelBooking/SummaryBar";
25
+ import NumericStepper from "./components/NumericStepper/NumericStepper";
26
+ import FlightSummaryBar from "./components/TravelBooking/FlightSummary";
27
+ import HotelSummaryBar from "./components/TravelBooking/HotelSummary";
28
+ import TabSelector from "./components/TravelBooking/TabSelector";
29
+ import FlightForm from "./components/TravelBooking/FlightForm";
30
+ import DateRangePicker from "./components/DateRangePicker/DateRangePicker";
31
+ import HotelForm from "./components/TravelBooking/HotelForm";
32
+ import CarRentalForm from "./components/TravelBooking/CarRentalForm";
33
+ import TravelBooking from "./components/TravelBooking/TravelBooking";
34
+ import { GestureHandlerRootView } from "react-native-gesture-handler";
12
35
  // import BRANDS from "./constants/BRANDS";
13
36
 
14
37
  export default function App() {
15
38
  const { theme } = useTheme();
16
39
  const [filtersVisible, setFiltersVisible] = useState(false);
40
+ const [mode, setMode] = useState<"flight" | "hotel">("flight");
17
41
 
18
42
  // Define some sort options for the filter
19
43
  const sortOptions = [
@@ -80,19 +104,59 @@ export default function App() {
80
104
  ...item,
81
105
  text: "Online shopping",
82
106
  }));
107
+ const debounceTimerRef = useRef<NodeJS.Timeout | null>(null);
83
108
 
84
109
  return (
85
- <RelatedProvider>
86
- <Filters
87
- sortOptions={[
88
- { id: 1, name: "Newest First", value: "newest", checked: true},
89
- { id: 2, name: "Oldest First", value: "oldest" },
90
- { id: 3, name: "Highest Rated", value: "rated_desc" },
91
- ]}
92
- // brands={BRANDS}
93
- onActionButtonPress={console.log}
94
- />
95
- </RelatedProvider>
110
+ <GestureHandlerRootView>
111
+ <RelatedProvider>
112
+ {/* <View> */}
113
+ <SafeAreaView
114
+ style={{ padding: 10, flex: 1, backgroundColor: theme.background }}
115
+ >
116
+ {/* <TravelBooking
117
+ onInputFocus={console.log}
118
+ onTextChange={(text)=> {
119
+ if(debounceTimerRef.current){
120
+ clearTimeout(debounceTimerRef.current)
121
+ }
122
+ debounceTimerRef.current = setTimeout(()=>{console.log(text)}, 300)
123
+ }}
124
+ // labelStyle={{color: "red"}}
125
+ // // searchButtonStyle={{backgroundColor: "blue"}}
126
+ // flightFormProps={{
127
+ // // returnLabel: "Test",
128
+ // labelStyle: {color:"blue"},
129
+ // // inputGroupStyle: {height}
130
+ // }}
131
+ ></TravelBooking> */}
132
+ {/* </ScrollView> */}
133
+ <Banner
134
+ backgroundImage={require("@/assets/images/namshi-banner.png")}
135
+ buttonText="Redeem Now"
136
+ onButtonPress={() => Alert.alert("Button pressed")}
137
+ onBannerPress={() => Alert.alert("Banner pressed")}
138
+ height={200}
139
+ contentAlignment="bottom"
140
+ icon={<Ionicons name="gift-outline" size={20} color="#FFFFFF" />}
141
+ iconPosition="left"
142
+ />
143
+ <Popup
144
+ visible={true}
145
+ onClose={()=>{} }
146
+ showCloseIcon={true}
147
+ title="ترقية إلى النسخة المميزة"
148
+ subtitle="استمتع بمزايا حصرية"
149
+ content="احصل على جميع الميزات المتقدمة والمحتوى الحصري بدون إعلانات. اشترك الآن واستمتع بتجربة كاملة مع تحديثات مجانية لمدة عام كامل."
150
+ primaryButtonText="ترقية الآن"
151
+ secondaryButtonText="ليس الآن"
152
+ onPrimaryButtonPress={()=>{}}
153
+ onSecondaryButtonPress={()=>{}}
154
+ isRTL={true}
155
+ />
156
+ </SafeAreaView>
157
+ {/* </View> */}
158
+ </RelatedProvider>
159
+ </GestureHandlerRootView>
96
160
  );
97
161
  }
98
162
 
@@ -0,0 +1,410 @@
1
+ import { ThemeType, useTheme } from "@/theme"; // Adjust path if needed
2
+ import React, { useCallback, useMemo, useState, useEffect } from "react";
3
+ import {
4
+ View,
5
+ Text,
6
+ TouchableOpacity,
7
+ StyleSheet,
8
+ StyleProp,
9
+ ViewStyle,
10
+ TextStyle,
11
+ Modal,
12
+ } from "react-native";
13
+ import { Calendar, DateData } from "react-native-calendars";
14
+ import { format, parseISO, addDays, eachDayOfInterval, isValid } from "date-fns";
15
+ import { MarkedDates } from "react-native-calendars/src/types";
16
+
17
+ // --- Helper Function ---
18
+ const formatDateDisplay = (date: Date | string | undefined): string => {
19
+ if (!date) return "";
20
+ try {
21
+ const dateObj = typeof date === "string" ? parseISO(date) : date;
22
+ if (!isValid(dateObj)) return "";
23
+ return format(dateObj, "MMM d, yyyy").toUpperCase();
24
+ } catch (e) {
25
+ console.error("Error formatting date:", e);
26
+ return "";
27
+ }
28
+ };
29
+
30
+ // --- Component Props ---
31
+ interface DateRangePickerProps {
32
+ initialDepartureDate?: string;
33
+ initialReturnDate?: string;
34
+ isOneWay?: boolean;
35
+ onDatesChange: (dates: {
36
+ departure: string | undefined;
37
+ return: string | undefined;
38
+ }) => void;
39
+
40
+ departureLabel?: string;
41
+ returnLabel?: string;
42
+ placeholder?: string;
43
+ calendarThemeOverrides?: object;
44
+
45
+ // Style Props
46
+ outerContainerStyle?: StyleProp<ViewStyle>;
47
+ inputContainerStyle?: StyleProp<ViewStyle>;
48
+ inputGroupStyle?: StyleProp<ViewStyle>; // Applied to both label group and input group
49
+ labelStyle?: StyleProp<TextStyle>;
50
+ inputTextStyle?: StyleProp<TextStyle>;
51
+ separatorStyle?: StyleProp<ViewStyle>;
52
+ calendarContainerStyle?: StyleProp<ViewStyle>;
53
+ }
54
+
55
+ // --- Component ---
56
+ const DateRangePicker: React.FC<DateRangePickerProps> = ({
57
+ initialDepartureDate,
58
+ initialReturnDate,
59
+ isOneWay = false,
60
+ onDatesChange,
61
+ departureLabel = "DEPARTURE",
62
+ returnLabel = "RETURN",
63
+ placeholder = "Select Date",
64
+ calendarThemeOverrides = {},
65
+ outerContainerStyle,
66
+ inputContainerStyle,
67
+ inputGroupStyle, // Will be used for label groups too
68
+ labelStyle,
69
+ inputTextStyle,
70
+ separatorStyle,
71
+ calendarContainerStyle,
72
+ }) => {
73
+ const { theme, isRTL } = useTheme();
74
+ const styles = useMemo(() => themedStyles(theme, isRTL), [theme, isRTL]);
75
+
76
+ // --- State ---
77
+ const [departureDate, setDepartureDate] = useState<string | undefined>(
78
+ initialDepartureDate
79
+ );
80
+ const [returnDate, setReturnDate] = useState<string | undefined>(
81
+ isOneWay ? undefined : initialReturnDate
82
+ );
83
+ const [isCalendarVisible, setIsCalendarVisible] = useState(false);
84
+
85
+ useEffect(() => {
86
+ setDepartureDate(initialDepartureDate);
87
+ }, [initialDepartureDate]);
88
+
89
+ useEffect(() => {
90
+ setReturnDate(isOneWay ? undefined : initialReturnDate);
91
+ }, [initialReturnDate, isOneWay]);
92
+
93
+ useEffect(() => {
94
+ if (isOneWay && returnDate) {
95
+ setReturnDate(undefined);
96
+ onDatesChange({ departure: departureDate, return: undefined });
97
+ }
98
+ }, [isOneWay, returnDate, departureDate, onDatesChange]);
99
+
100
+ // --- Handlers ---
101
+ const handleDayPress = useCallback(
102
+ (day: DateData) => {
103
+ let newDeparture = departureDate;
104
+ let newReturn = returnDate;
105
+ let shouldCloseCalendar = false;
106
+
107
+ if (isOneWay) {
108
+ newDeparture = day.dateString;
109
+ newReturn = undefined;
110
+ shouldCloseCalendar = true;
111
+ } else {
112
+ if (!newDeparture || (newDeparture && newReturn)) {
113
+ newDeparture = day.dateString;
114
+ newReturn = undefined;
115
+ } else if (newDeparture && !newReturn) {
116
+ try {
117
+ const depDate = parseISO(newDeparture);
118
+ const selectedDate = parseISO(day.dateString);
119
+ if (isValid(depDate) && isValid(selectedDate)) {
120
+ if (selectedDate >= depDate) {
121
+ newReturn = day.dateString;
122
+ shouldCloseCalendar = true;
123
+ } else {
124
+ newDeparture = day.dateString;
125
+ newReturn = undefined;
126
+ }
127
+ } else {
128
+ console.error("Invalid date encountered during selection");
129
+ newDeparture = day.dateString;
130
+ newReturn = undefined;
131
+ }
132
+ } catch (e) {
133
+ console.error("Error parsing dates during selection:", e);
134
+ newDeparture = day.dateString;
135
+ newReturn = undefined;
136
+ }
137
+ }
138
+ }
139
+
140
+ setDepartureDate(newDeparture);
141
+ setReturnDate(newReturn);
142
+ onDatesChange({ departure: newDeparture, return: newReturn });
143
+
144
+ if (shouldCloseCalendar) {
145
+ setIsCalendarVisible(false);
146
+ }
147
+ },
148
+ [departureDate, returnDate, isOneWay, onDatesChange]
149
+ );
150
+
151
+ const markedDates = useMemo((): MarkedDates => {
152
+ const marked: MarkedDates = {};
153
+ const primaryColor = theme.primary;
154
+ const onPrimaryColor = theme.onPrimary;
155
+ const rangeColor = theme.secondary;
156
+ const onRangeColor = theme.onSecondary;
157
+
158
+ if (departureDate) {
159
+ marked[departureDate] = {
160
+ startingDay: !returnDate || departureDate === returnDate,
161
+ color: primaryColor,
162
+ textColor: onPrimaryColor,
163
+ selected: true,
164
+ };
165
+ }
166
+ if (returnDate) {
167
+ marked[returnDate] = {
168
+ ...marked[returnDate],
169
+ endingDay: true,
170
+ color: primaryColor,
171
+ textColor: onPrimaryColor,
172
+ selected: true,
173
+ };
174
+ }
175
+
176
+ if (departureDate && returnDate && departureDate !== returnDate) {
177
+ try {
178
+ const start = addDays(parseISO(departureDate), 1);
179
+ const end = parseISO(returnDate);
180
+
181
+ if (isValid(start) && isValid(end) && end > start) {
182
+ const interval = eachDayOfInterval({ start, end });
183
+ interval.forEach((date) => {
184
+ const dateString = format(date, "yyyy-MM-dd");
185
+ if (dateString !== returnDate) {
186
+ marked[dateString] = {
187
+ color: rangeColor,
188
+ textColor: onRangeColor,
189
+ selected: true,
190
+ };
191
+ }
192
+ });
193
+ }
194
+ } catch (e) {
195
+ console.error("Error creating date interval:", e);
196
+ }
197
+ }
198
+
199
+ return marked;
200
+ }, [departureDate, returnDate, theme]);
201
+
202
+ // --- Calendar Theme ---
203
+ const calendarTheme = useMemo(() => {
204
+ return {
205
+ backgroundColor: theme.surface,
206
+ calendarBackground: theme.surface,
207
+ textSectionTitleColor: theme.onSurface,
208
+ selectedDayBackgroundColor: theme.primary,
209
+ selectedDayTextColor: theme.onPrimary,
210
+ todayTextColor: theme.primary,
211
+ dayTextColor: theme.onSurface,
212
+ textDisabledColor: theme.disabled,
213
+ dotColor: theme.primary,
214
+ selectedDotColor: theme.onPrimary,
215
+ arrowColor: theme.primary,
216
+ disabledArrowColor: theme.disabled,
217
+ monthTextColor: theme.onSurface,
218
+ indicatorColor: theme.primary,
219
+ textDayFontWeight: "500",
220
+ textMonthFontWeight: "bold",
221
+ textDayHeaderFontWeight: "bold",
222
+ textDayFontSize: 14,
223
+ textMonthFontSize: 16,
224
+ textDayHeaderFontSize: 12,
225
+ ...calendarThemeOverrides,
226
+ };
227
+ }, [theme, calendarThemeOverrides]);
228
+
229
+ const displayDeparture = formatDateDisplay(departureDate) || placeholder;
230
+ const displayReturn = formatDateDisplay(returnDate) || placeholder;
231
+
232
+ return (
233
+ <>
234
+ <View style={[styles.outerContainer, outerContainerStyle]}>
235
+ {/* Labels Container */}
236
+ <View style={styles.labelsContainer}>
237
+ {/* Departure Label Group */}
238
+ <View style={[styles.labelGroup, inputGroupStyle]}>
239
+ <Text style={[styles.label, labelStyle]}>{departureLabel}</Text>
240
+ </View>
241
+
242
+ {!isOneWay && (
243
+ <>
244
+ {/* Return Label Group */}
245
+ <View style={[styles.labelGroup, inputGroupStyle]}>
246
+ <Text style={[styles.label, labelStyle]}>{returnLabel}</Text>
247
+ </View>
248
+ </>
249
+ )}
250
+ </View>
251
+
252
+ {/* Input Box */}
253
+ <TouchableOpacity
254
+ style={[styles.inputContainer, inputContainerStyle]}
255
+ onPress={() => setIsCalendarVisible(true)}
256
+ activeOpacity={0.7}
257
+ >
258
+ {/* Departure Date Input Area */}
259
+ <View style={[styles.dateInputGroup, inputGroupStyle]}>
260
+ <Text
261
+ style={[
262
+ styles.inputText,
263
+ !departureDate && styles.placeholderText,
264
+ inputTextStyle,
265
+ ]}
266
+ numberOfLines={1}
267
+ ellipsizeMode="tail"
268
+ >
269
+ {displayDeparture}
270
+ </Text>
271
+ </View>
272
+
273
+ {!isOneWay && (
274
+ <>
275
+ {/* Actual Separator */}
276
+ <View style={[styles.dateSeparator, separatorStyle]} />
277
+
278
+ {/* Return Date Input Area */}
279
+ <View style={[styles.dateInputGroup, inputGroupStyle]}>
280
+ <Text
281
+ style={[
282
+ styles.inputText,
283
+ !returnDate && styles.placeholderText,
284
+ inputTextStyle,
285
+ ]}
286
+ numberOfLines={1}
287
+ ellipsizeMode="tail"
288
+ >
289
+ {displayReturn}
290
+ </Text>
291
+ </View>
292
+ </>
293
+ )}
294
+ </TouchableOpacity>
295
+ </View>
296
+
297
+ {/* Calendar Modal */}
298
+ <Modal
299
+ transparent={true}
300
+ visible={isCalendarVisible}
301
+ onRequestClose={() => setIsCalendarVisible(false)}
302
+ animationType="fade"
303
+ >
304
+ <TouchableOpacity
305
+ style={styles.modalOverlay}
306
+ activeOpacity={1}
307
+ onPressOut={() => setIsCalendarVisible(false)}
308
+ >
309
+ <View onStartShouldSetResponder={() => true}>
310
+ <View style={[styles.calendarContainer, calendarContainerStyle]}>
311
+ <Calendar
312
+ current={departureDate || format(new Date(), "yyyy-MM-dd")}
313
+ onDayPress={handleDayPress}
314
+ markedDates={markedDates}
315
+ markingType={"period"}
316
+ theme={calendarTheme}
317
+ firstDay={1}
318
+ monthFormat={"MMM yyyy"}
319
+ />
320
+ </View>
321
+ </View>
322
+ </TouchableOpacity>
323
+ </Modal>
324
+ </>
325
+ );
326
+ };
327
+
328
+ // --- Styles ---
329
+ const themedStyles = (theme: ThemeType, isRTL: boolean) =>
330
+ StyleSheet.create({
331
+ outerContainer: {
332
+ // flex: 1,
333
+ },
334
+ labelsContainer: {
335
+ flexDirection: isRTL ? "row-reverse" : "row",
336
+ marginBottom: 4,
337
+ alignItems: "center",
338
+ },
339
+ labelGroup: {
340
+ flex: 1,
341
+ justifyContent: "center",
342
+ },
343
+ label: {
344
+ color: theme.labelText,
345
+ fontSize: 12,
346
+ fontWeight: "600",
347
+ textTransform: "uppercase",
348
+ textAlign: isRTL ? "right" : "left",
349
+ },
350
+ labelSeparatorPlaceholder: {
351
+ width: 1,
352
+ backgroundColor: "transparent",
353
+ marginHorizontal: 8,
354
+ },
355
+ inputContainer: {
356
+ flexDirection: isRTL ? "row-reverse" : "row",
357
+ borderColor: theme.border,
358
+ borderWidth: 1,
359
+ borderRadius: 8,
360
+ minHeight: 50,
361
+ backgroundColor: theme.surface,
362
+ alignItems: "center",
363
+ paddingHorizontal: 12,
364
+ overflow: "hidden",
365
+ },
366
+ dateInputGroup: {
367
+ flex: 1,
368
+ paddingVertical: 8,
369
+ justifyContent: "center",
370
+ },
371
+ inputText: {
372
+ color: theme.onSurface,
373
+ fontSize: 15,
374
+ fontWeight: "500",
375
+ textAlign: isRTL ? "right" : "left",
376
+ },
377
+ placeholderText: {
378
+ color: theme.helper,
379
+ fontWeight: "400",
380
+ },
381
+ dateSeparator: {
382
+ width: 1,
383
+ height: "60%",
384
+ backgroundColor: theme.border,
385
+ marginHorizontal: 8,
386
+ },
387
+ modalOverlay: {
388
+ flex: 1,
389
+ backgroundColor: "rgba(0, 0, 0, 0.6)",
390
+ justifyContent: "center",
391
+ padding: 20,
392
+ },
393
+ calendarContainer: {
394
+ backgroundColor: theme.surface,
395
+ borderRadius: 12,
396
+ paddingVertical: 5,
397
+ paddingHorizontal: 5,
398
+ width: "100%",
399
+ shadowColor: "#000",
400
+ shadowOffset: {
401
+ width: 0,
402
+ height: 4,
403
+ },
404
+ shadowOpacity: 0.15,
405
+ shadowRadius: 10,
406
+ elevation: 8,
407
+ },
408
+ });
409
+
410
+ export default DateRangePicker;
@@ -0,0 +1,2 @@
1
+ // export { default as DateRangePicker} from "./DateRangePicker";
2
+ // export * from "./DateRangePicker";
@@ -223,7 +223,7 @@
223
223
 
224
224
  setCheckedItem(null);
225
225
  setSelectedBrands(resetBrands);
226
- setPointsRange({ min: rangeInitialMin, max: rangeInitialMax });
226
+ setPointsRange({ min: rangeMinLimit, max: rangeInitialMax });
227
227
  setResetCounter((prev) => prev + 1);
228
228
  };
229
229
 
@@ -177,7 +177,7 @@ const createStyles = (theme: ThemeType) =>
177
177
  borderRadius: 8,
178
178
  backgroundColor: theme.inputBackground, // Use inputBackground
179
179
  alignItems: 'center',
180
- minHeight: 48,
180
+ // minHeight: 48,
181
181
  },
182
182
  focusedInput: {
183
183
  borderColor: theme.primary, // Use primary for focus indication
@@ -0,0 +1,117 @@
1
+ // NumericStepper.tsx
2
+ import React, { useMemo } from "react";
3
+ import {
4
+ View,
5
+ Text,
6
+ TouchableOpacity,
7
+ StyleSheet,
8
+ StyleProp,
9
+ ViewStyle,
10
+ TextStyle,
11
+ } from "react-native";
12
+ import { ThemeType, useTheme } from "../../theme";
13
+
14
+ export interface NumericStepperProps {
15
+ value: number;
16
+ minValue?: number;
17
+ maxValue?: number;
18
+ step?: number;
19
+ onIncrement: () => void;
20
+ onDecrement: () => void;
21
+ isRTL?: boolean;
22
+ style?: StyleProp<ViewStyle>;
23
+ buttonStyle?: StyleProp<ViewStyle>;
24
+ buttonTextStyle?: StyleProp<TextStyle>;
25
+ valueTextStyle?: StyleProp<TextStyle>;
26
+ disabledOpacity?: number;
27
+ }
28
+
29
+ const NumericStepper: React.FC<NumericStepperProps> = ({
30
+ value,
31
+ minValue = 0,
32
+ maxValue = Number.MAX_SAFE_INTEGER,
33
+ onIncrement,
34
+ onDecrement,
35
+ isRTL: isRTLProp,
36
+ style,
37
+ buttonStyle,
38
+ buttonTextStyle,
39
+ valueTextStyle,
40
+ disabledOpacity = 0.5,
41
+ }) => {
42
+ const { theme, isRTL: themeRTL } = useTheme();
43
+ const isRTL = isRTLProp ?? themeRTL;
44
+
45
+ const styles = useMemo(() => themedStyles(theme, isRTL), [theme, isRTL]);
46
+
47
+ const isDecrementDisabled = value <= minValue;
48
+ const isIncrementDisabled = value >= maxValue;
49
+
50
+ return (
51
+ <View style={[styles.container, style]}>
52
+ <TouchableOpacity
53
+ style={[
54
+ styles.button,
55
+ buttonStyle,
56
+ isDecrementDisabled && { opacity: disabledOpacity },
57
+ ]}
58
+ onPress={onDecrement}
59
+ disabled={isDecrementDisabled}
60
+ hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
61
+ >
62
+ <Text style={[styles.buttonText, buttonTextStyle]}>
63
+ -
64
+ </Text>
65
+ </TouchableOpacity>
66
+
67
+ <Text style={[styles.valueText, valueTextStyle]}>
68
+ {value}
69
+ </Text>
70
+
71
+ <TouchableOpacity
72
+ style={[
73
+ styles.button,
74
+ buttonStyle,
75
+ isIncrementDisabled && { opacity: disabledOpacity },
76
+ ]}
77
+ onPress={onIncrement}
78
+ disabled={isIncrementDisabled}
79
+ hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
80
+ >
81
+ <Text style={[styles.buttonText, buttonTextStyle]}>
82
+ +
83
+ </Text>
84
+ </TouchableOpacity>
85
+ </View>
86
+ );
87
+ };
88
+
89
+ const themedStyles = (theme: ThemeType, isRTL: boolean) =>
90
+ StyleSheet.create({
91
+ container: {
92
+ flexDirection: isRTL ? "row-reverse" : "row",
93
+ alignItems: "center",
94
+ },
95
+ button: {
96
+ backgroundColor: theme.secondary,
97
+ width: 36,
98
+ height: 36,
99
+ borderRadius: 18,
100
+ justifyContent: "center",
101
+ alignItems: "center",
102
+ },
103
+ buttonText: {
104
+ // fontSize: 20,
105
+ fontWeight: "bold",
106
+ color: theme.onSecondary
107
+ },
108
+ valueText: {
109
+ fontSize: 16,
110
+ minWidth: 50,
111
+ textAlign: "center",
112
+ marginHorizontal: 8,
113
+ color: theme.onSurface
114
+ },
115
+ });
116
+
117
+ export default NumericStepper;
@@ -0,0 +1,2 @@
1
+ export {default as NumericStepper} from "./NumericStepper";
2
+ export * from "./NumericStepper";