newcandies 0.1.40 → 0.1.41

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "newcandies",
3
- "version": "0.1.40",
3
+ "version": "0.1.41",
4
4
  "description": "Scaffold Expo Router + Uniwind React Native apps with layered templates.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,11 @@
1
+ import { Text, View } from 'react-native';
2
+
3
+ const Home = () => {
4
+ return (
5
+ <View>
6
+ <Text>Home</Text>
7
+ </View>
8
+ );
9
+ };
10
+
11
+ export default Home;
@@ -1,264 +0,0 @@
1
- import Ionicons from '@expo/vector-icons/Ionicons';
2
- import BottomSheet, {
3
- BottomSheetBackdrop,
4
- BottomSheetBackdropProps,
5
- BottomSheetView,
6
- } from '@gorhom/bottom-sheet';
7
- import { Calendar, fromDateId, toDateId, useDateRange } from '@marceloterreiro/flash-calendar';
8
- import { nanoid } from 'nanoid/non-secure';
9
- import { toast } from 'sonner-native';
10
-
11
- import { useQuery } from '@tanstack/react-query';
12
- import {
13
- addMonths,
14
- differenceInDays,
15
- isBefore,
16
- isSameMonth,
17
- startOfMonth,
18
- subMonths,
19
- } from 'date-fns';
20
- import { router, useLocalSearchParams } from 'expo-router';
21
- import { SquircleButton } from 'expo-squircle-view';
22
- import { useCallback, useMemo, useRef, useState } from 'react';
23
- import { Pressable, ScrollView, View } from 'react-native';
24
- import Container from '~/components/container';
25
- import Header from '~/components/header';
26
- import LoadingIndicator from '~/components/loading-indicator';
27
- import AmenitiesList from '~/components/property/amenities-list';
28
- import PropertyImage from '~/components/property/property-image';
29
- import Text from '~/components/text';
30
- import { client } from '~/core/api/client';
31
- import { today } from '~/core/constants';
32
- import useShoppingCartStore from '~/core/store';
33
- import { calendarTheme } from '~/core/theme/calendar-theme';
34
- import { PRIMARY } from '~/core/theme/colors';
35
-
36
- type Props = {};
37
- const Property = ({}: Props) => {
38
- const { id } = useLocalSearchParams();
39
-
40
- const { data: property, isLoading } = useQuery<Property>({
41
- queryKey: ['property' + id],
42
- queryFn: async () => {
43
- const { data } = await client.get(`/properties/${id}`);
44
- return data.property;
45
- },
46
- });
47
-
48
- const { addItem } = useShoppingCartStore();
49
-
50
- const { calendarActiveDateRanges, onCalendarDayPress } = useDateRange();
51
-
52
- console.log({ calendarActiveDateRanges });
53
-
54
- const bottomSheetRef = useRef<BottomSheet>(null);
55
-
56
- const snapPoints = useMemo(() => ['60%'], []);
57
-
58
- const renderBackdrop = useCallback((props: BottomSheetBackdropProps) => {
59
- return (
60
- <BottomSheetBackdrop
61
- {...props}
62
- disappearsOnIndex={-1}
63
- appearsOnIndex={0}
64
- pressBehavior={'close'}
65
- />
66
- );
67
- }, []);
68
-
69
- const calculateDays = () => {
70
- if (!calendarActiveDateRanges[0]?.startId) return 0;
71
- if (!calendarActiveDateRanges[0]?.endId) return 1;
72
-
73
- const startDate = new Date(calendarActiveDateRanges[0].startId);
74
- const endDate = new Date(calendarActiveDateRanges[0].endId);
75
-
76
- return differenceInDays(endDate, startDate) + 1;
77
- };
78
-
79
- const hasSelectedDates = Boolean(calendarActiveDateRanges[0]?.startId);
80
- const [calendarMonthId, setCalendarMonthId] = useState(today);
81
-
82
- const nextMonth = () => {
83
- const month = addMonths(calendarMonthId, 1);
84
- setCalendarMonthId(toDateId(month));
85
- };
86
-
87
- const currentDisplayMonth = fromDateId(calendarMonthId);
88
- const canGoBack =
89
- !isSameMonth(currentDisplayMonth, today) && !isBefore(currentDisplayMonth, startOfMonth(today));
90
-
91
- const prevMonth = () => {
92
- if (canGoBack) {
93
- const month = subMonths(calendarMonthId, 1);
94
- setCalendarMonthId(toDateId(month));
95
- }
96
- };
97
- if (isLoading || !property) {
98
- return <LoadingIndicator />;
99
- }
100
- const days = calculateDays();
101
- const totalPrice = days * property.price_per_night;
102
-
103
- return (
104
- <Container>
105
- <Header title="Property" />
106
- <ScrollView className="flex-1 bg-gray-100 p-4">
107
- <PropertyImage
108
- imageUrl={property?.images[1]}
109
- isFavorite={property?.is_favorite}
110
- rating={5}
111
- />
112
- <View className="flex flex-row items-center justify-between">
113
- <Text variant="subtitle-primary" className="mt-4">
114
- {property.name}
115
- </Text>
116
- <View className="flex flex-row items-center justify-center">
117
- <Ionicons name="pricetag" size={12} color={PRIMARY} />
118
- <Text variant="body-primary" className="ml-2">
119
- ${property.price_per_night} per night
120
- </Text>
121
- </View>
122
- </View>
123
- <View className="flex flex-row items-center">
124
- <Ionicons name="location" size={16} color={PRIMARY} />
125
- <Text variant="body-primary" className="">
126
- {property.city}, {property.country}
127
- </Text>
128
- </View>
129
- <Text variant="body" className="mt-1 text-gray-700">
130
- {property.description}
131
- </Text>
132
- <AmenitiesList amenities={property.amenities} />
133
- </ScrollView>
134
-
135
- <BottomSheet
136
- ref={bottomSheetRef}
137
- snapPoints={snapPoints}
138
- backdropComponent={renderBackdrop}
139
- index={-1}
140
- enablePanDownToClose={true}
141
- enableDynamicSizing={false}>
142
- <BottomSheetView style={{ flex: 1 }}>
143
- <View className="my-4 flex flex-row items-center justify-between px-4">
144
- <View className="flex flex-row items-center justify-center">
145
- <Ionicons name="wallet" color={PRIMARY} size={24} />
146
- <Text variant="subtitle" className="mx-4">
147
- Price : ${hasSelectedDates ? totalPrice : property.price_per_night}
148
- {!hasSelectedDates && ' per night'}
149
- </Text>
150
- </View>
151
- </View>
152
- <BottomSheetView style={{ flex: 1, paddingHorizontal: 4, position: 'relative' }}>
153
- <View className="mt-20 flex flex-row justify-between">
154
- <Pressable onPress={prevMonth} disabled={!canGoBack}>
155
- <Ionicons name="arrow-back" size={24} color={canGoBack ? PRIMARY : 'gray'} />
156
- </Pressable>
157
- <Pressable onPress={nextMonth}>
158
- <Ionicons name="arrow-forward" size={24} color={PRIMARY} />
159
- </Pressable>
160
- </View>
161
-
162
- <Calendar
163
- calendarMonthId={calendarMonthId}
164
- calendarActiveDateRanges={calendarActiveDateRanges}
165
- calendarMinDateId={today}
166
- onCalendarDayPress={onCalendarDayPress}
167
- theme={calendarTheme}
168
- />
169
- <SquircleButton
170
- backgroundColor={PRIMARY}
171
- cornerSmoothing={100}
172
- onPress={() => {
173
- bottomSheetRef.current?.close();
174
-
175
- if (!hasSelectedDates || !calendarActiveDateRanges[0]?.startId) {
176
- console.log('error: please select dates');
177
- return;
178
- }
179
-
180
- const cartItem: ICartItem = {
181
- id: 'cart' + nanoid(),
182
- image: property.images[0],
183
- name: property.name,
184
- product: property.id,
185
- price_per_night: property.price_per_night,
186
- quantity: 1,
187
- startDate: calendarActiveDateRanges[0].startId,
188
- endDate:
189
- calendarActiveDateRanges[0]?.endId ?? calendarActiveDateRanges[0].startId,
190
- days: calculateDays(),
191
- };
192
- addItem(cartItem);
193
- bottomSheetRef.current?.close();
194
- }}
195
- preserveSmoothing
196
- className="m-8 flex flex-row items-center justify-center px-4 "
197
- style={{
198
- paddingVertical: 16,
199
- position: 'absolute',
200
- bottom: -120,
201
- left: 0,
202
- right: 0,
203
- }}
204
- borderRadius={24}>
205
- <Ionicons name="checkmark-circle" size={20} color={'white'} />
206
- <Text variant="button" className="mx-2 text-center">
207
- Confirm
208
- </Text>
209
- </SquircleButton>
210
- </BottomSheetView>
211
- </BottomSheetView>
212
- </BottomSheet>
213
-
214
- <View className="bottom-0 left-0 right-0 -z-10 mx-4 mt-auto flex flex-row items-center justify-center py-2">
215
- {hasSelectedDates ? (
216
- <Pressable
217
- className="mr-4"
218
- onPress={() => {
219
- bottomSheetRef.current?.expand();
220
- }}>
221
- <View className="flex flex-row items-center">
222
- <Ionicons name="pricetag" color={PRIMARY} size={16} />
223
- <Text variant="body-primary" className="text-center">
224
- ${totalPrice}
225
- </Text>
226
- </View>
227
- <Text variant="caption" className="text-center underline">
228
- {days === 1 ? '1 Night' : `${days} nights`}
229
- </Text>
230
- </Pressable>
231
- ) : (
232
- <Pressable
233
- className="mr-4 flex flex-row items-center"
234
- onPress={() => {
235
- bottomSheetRef.current?.expand();
236
- }}>
237
- <Ionicons name="calendar-outline" size={24} color={PRIMARY} />
238
- <Text variant="body-primary" className="ml-2 text-center underline">
239
- Select dates
240
- </Text>
241
- </Pressable>
242
- )}
243
- <SquircleButton
244
- onPress={() => {
245
- toast.success('Property added to cart');
246
- router.push('/checkout');
247
- }}
248
- className="flex-grow"
249
- backgroundColor={PRIMARY}
250
- borderRadius={16}
251
- style={{
252
- paddingVertical: 16,
253
- marginVertical: 4,
254
- }}>
255
- <Text variant="button" className="text-center">
256
- Book Now
257
- </Text>
258
- </SquircleButton>
259
- </View>
260
- </Container>
261
- );
262
- };
263
-
264
- export default Property;