Browse Source

Merge branch 'dev' into 42-make-charging-page

Ian Fung 1 year ago
parent
commit
7e17f80d35

+ 7 - 1
app/(public)/test.tsx

@@ -1,6 +1,12 @@
 import React from 'react';
 import TestPage from '../../component/test/page';
+import ReservationLocationPage from '../../component/reservationLocationPage/reservationLocationPage';
+import { View } from 'react-native';
 
 export default function Test() {
-    return <TestPage />;
+    return (
+        <View className='flex-1'>
+            <ReservationLocationPage />
+        </View>
+    );
 }

+ 1 - 1
app/_layout.tsx

@@ -19,7 +19,7 @@ export default function RootLayout() {
                     <Stack.Screen
                         name="(public)/test"
                         options={{
-                            headerShown: true,
+                            headerShown: false,
                             title: 'Test Component Page'
                         }}
                     />

BIN
assets/car1.png


BIN
assets/car2.png


+ 371 - 0
component/bookingMenuPage/makingBookingPage.tsx

@@ -0,0 +1,371 @@
+import {
+    View,
+    Text,
+    ScrollView,
+    Pressable,
+    StyleSheet,
+    Image,
+    useWindowDimensions
+} from 'react-native';
+import React from 'react';
+import { SafeAreaView } from 'react-native-safe-area-context';
+import Svg, { Path, Rect } from 'react-native-svg';
+import { router } from 'expo-router';
+import NormalButton from '../global/normal_button';
+
+import { SceneMap, TabBar, TabView } from 'react-native-tab-view';
+
+interface ChargingStationTabViewProps {
+    titles: string[];
+}
+
+const ChargingStationTabView: React.FC<ChargingStationTabViewProps> = ({
+    titles
+}) => {
+    const layout = useWindowDimensions();
+
+    //tab 1
+    const FirstRoute = () => (
+        <ScrollView style={{ flex: 1, marginHorizontal: '5%' }}>
+            <Text className="text-lg" style={styles.text}>
+                這是一段有關充電站的說明
+            </Text>
+        </ScrollView>
+    );
+
+    //tab 2
+    const SecondRoute = () => (
+        <ScrollView style={{ flex: 1, marginHorizontal: '5%' }}>
+            <Text className="text-lg " style={styles.text}>
+                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
+                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
+                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
+            </Text>
+        </ScrollView>
+    );
+
+    const renderScene = SceneMap({
+        firstRoute: FirstRoute,
+        secondRoute: SecondRoute
+    });
+    const [routes] = React.useState([
+        { key: 'firstRoute', title: titles[0] },
+        { key: 'secondRoute', title: titles[1] }
+    ]);
+    const [index, setIndex] = React.useState(0);
+
+    const renderTabBar = (props: any) => (
+        <TabBar
+            {...props}
+            renderLabel={({ route, focused }) => (
+                <Text
+                    style={{
+                        color: focused ? '#000000' : '#CCCCCC',
+                        fontWeight: focused ? '300' : 'thin',
+                        fontSize: 17
+                    }}
+                >
+                    {route.title}
+                </Text>
+            )}
+            indicatorStyle={{
+                backgroundColor: '#000000',
+                height: 1
+            }}
+            style={{
+                backgroundColor: 'white',
+                elevation: 0,
+                marginHorizontal: 15,
+                borderBottomWidth: 0.5
+            }}
+        />
+    );
+    return (
+        <TabView
+            navigationState={{ index, routes }}
+            renderScene={renderScene}
+            onIndexChange={setIndex}
+            initialLayout={{ width: layout.width }}
+            renderTabBar={renderTabBar}
+        />
+    );
+};
+
+const PreviousPageSvg = () => (
+    <Svg width="28" height="28" viewBox="0 0 28 28" fill="none">
+        <Path
+            d="M7.04167 15.6667L16.375 25L14 27.3334L0.666672 14L14 0.666687L16.375 3.00002L7.04167 12.3334H27.3333V15.6667H7.04167Z"
+            fill="black"
+        />
+    </Svg>
+);
+
+const CheckLogoSvg = () => (
+    <Svg width="20" height="20" viewBox="0 0 20 20" fill="none">
+        <Rect width="20" height="20" rx="10" fill="#02677D" />
+        <Path
+            d="M7.95837 15L3.20837 10.25L4.39587 9.06251L7.95837 12.625L15.6042 4.97917L16.7917 6.16667L7.95837 15Z"
+            fill="white"
+        />
+    </Svg>
+);
+
+const DirectionLogoSvg = () => (
+    <Svg width="20" height="20" viewBox="0 0 20 20" fill="none">
+        <Path
+            d="M6.87502 12.2917H8.12498V9.79166H11.4584V11.5785L13.8702 9.16668L11.4584 6.74685V8.5417H7.62821C7.41481 8.5417 7.23592 8.61358 7.09156 8.75733C6.9472 8.90108 6.87502 9.0792 6.87502 9.29168V12.2917ZM10.0016 17.8045C9.81357 17.8045 9.62831 17.7668 9.44581 17.6915C9.26331 17.6162 9.09655 17.5032 8.94552 17.3525L2.64748 11.0545C2.49684 10.9041 2.38386 10.738 2.30854 10.5562C2.23321 10.3745 2.19554 10.1896 2.19554 10.0016C2.19554 9.81358 2.23321 9.62833 2.30854 9.44583C2.38386 9.26333 2.49684 9.09656 2.64748 8.94554L8.94552 2.64749C9.09594 2.49686 9.26202 2.38388 9.44377 2.30856C9.62552 2.23322 9.8104 2.19556 9.99842 2.19556C10.1864 2.19556 10.3717 2.23322 10.5542 2.30856C10.7367 2.38388 10.9035 2.49686 11.0545 2.64749L17.3525 8.94554C17.5032 9.09595 17.6161 9.26204 17.6915 9.44379C17.7668 9.62554 17.8045 9.81042 17.8045 9.99843C17.8045 10.1864 17.7668 10.3717 17.6915 10.5542C17.6161 10.7367 17.5032 10.9035 17.3525 11.0545L11.0545 17.3525C10.9041 17.5032 10.738 17.6162 10.5562 17.6915C10.3745 17.7668 10.1896 17.8045 10.0016 17.8045ZM6.66667 13.3333L9.82371 16.4904C9.87179 16.5385 9.93056 16.5625 10 16.5625C10.0694 16.5625 10.1282 16.5385 10.1763 16.4904L16.4904 10.1763C16.5385 10.1282 16.5625 10.0695 16.5625 10C16.5625 9.93057 16.5385 9.87181 16.4904 9.82372L10.1763 3.50964C10.1282 3.46156 10.0694 3.43752 10 3.43752C9.93056 3.43752 9.87179 3.46156 9.82371 3.50964L3.50962 9.82372C3.46154 9.87181 3.4375 9.93057 3.4375 10C3.4375 10.0695 3.46154 10.1282 3.50962 10.1763L6.66667 13.3333Z"
+            fill="black"
+        />
+    </Svg>
+);
+
+const StarSvg = () => (
+    <Svg width="16" height="15" viewBox="0 0 16 15" fill="none">
+        <Path
+            d="M3.32507 14.9663L4.56544 9.65284L0.442368 6.08167L5.87314 5.61052L8.00007 0.600891L10.127 5.61052L15.5578 6.08167L11.4347 9.65284L12.6751 14.9663L8.00007 12.1451L3.32507 14.9663Z"
+            fill="white"
+        />
+    </Svg>
+);
+
+const MakingBookingPage = () => (
+    <SafeAreaView
+        style={{
+            flex: 1,
+            backgroundColor: 'white'
+        }}
+        edges={['right', 'top', 'left']}
+    >
+        <ScrollView className="flex-1 bg-white ">
+            <View className="h-[23vh] ">
+                <View className="pl-8 pt-8">
+                    <Pressable
+                        style={{ alignSelf: 'flex-start' }}
+                        onPress={() => {
+                            if (router.canGoBack()) {
+                                router.back();
+                            } else {
+                                router.replace('./');
+                            }
+                        }}
+                    >
+                        <PreviousPageSvg />
+                    </Pressable>
+                    <Text className="text-3xl mt-8">上環街市充電站</Text>
+                    <View className="flex-column">
+                        <View className="flex-row justify-between items-center mr-[5%]">
+                            <Text
+                                className="text-base"
+                                style={styles.grayColor}
+                            >
+                                香港上環皇后大道中345號
+                            </Text>
+                            <NormalButton
+                                title={
+                                    <View className="flex-row items-center justify-center text-center space-x-1">
+                                        <DirectionLogoSvg />
+                                        <Text className="text-base ">路線</Text>
+                                    </View>
+                                }
+                                onPress={() => console.log('abc')}
+                                extendedStyle={{
+                                    backgroundColor: '#E3F2F8',
+                                    borderRadius: 61,
+                                    paddingHorizontal: 20,
+                                    paddingVertical: 8
+                                }}
+                            />
+                        </View>
+                        <View className="flex-row space-x-2 items-center">
+                            <CheckLogoSvg />
+                            <Text>Walk-In</Text>
+                            <Text>400米</Text>
+                        </View>
+                    </View>
+                </View>
+            </View>
+
+            <View className="h-[50vh] bg-[#FAFAFA]">
+                <View className="h-[30vh] bg-[#e7f5f8]">
+                    <View className="flex-1 mx-[5%] ">
+                        <Text className="text-xl pt-4">選擇充電車輛</Text>
+
+                        <ScrollView
+                            horizontal={true}
+                            contentContainerStyle={{
+                                alignItems: 'center',
+                                flexDirection: 'row',
+                                marginVertical: 8
+                            }}
+                            className="space-x-2 flex-1  "
+                        >
+                            <View className="relative bg-white w-44 h-[90%] overflow-hidden rounded-lg items-center justify-center ">
+                                <View style={styles.topLeftTriangle} />
+                                <View className="absolute top-1 left-1">
+                                    <StarSvg />
+                                </View>
+                                <View className="items-center justify-center pt-4 space-y-2 ">
+                                    <Image
+                                        source={require('../../assets/car1.png')}
+                                        style={{ height: 72, width: 140 }}
+                                    />
+
+                                    <Text className="text-base text-[#222222]">
+                                        TESLA - Model 3
+                                    </Text>
+                                </View>
+                            </View>
+
+                            <View className="relative bg-white w-44 h-[90%] overflow-hidden rounded-lg items-center justify-center ">
+                                <View className="items-center justify-center pt-4 space-y-2 ">
+                                    <Image
+                                        source={require('../../assets/car2.png')}
+                                        style={{ height: 72, width: 140 }}
+                                    />
+
+                                    <Text className="text-base text-[#222222]">
+                                        TESLA - Model 3
+                                    </Text>
+                                </View>
+                            </View>
+                            <View className="relative bg-white w-44 h-[90%] overflow-hidden rounded-lg items-center justify-center ">
+                                <View className="items-center justify-center pt-4 space-y-2 ">
+                                    <Image
+                                        source={require('../../assets/car1.png')}
+                                        style={{ height: 72, width: 140 }}
+                                    />
+
+                                    <Text className="text-base text-[#222222]">
+                                        TESLA - Model 3
+                                    </Text>
+                                </View>
+                            </View>
+                            <View className="relative bg-white w-44 h-[90%] overflow-hidden rounded-lg items-center justify-center ">
+                                <View className="items-center justify-center pt-4 space-y-2 ">
+                                    <Image
+                                        source={require('../../assets/car2.png')}
+                                        style={{ height: 72, width: 140 }}
+                                    />
+
+                                    <Text className="text-base text-[#222222]">
+                                        TESLA - Model 3
+                                    </Text>
+                                </View>
+                            </View>
+                            <View className="relative bg-white w-44 h-[90%] overflow-hidden rounded-lg items-center justify-center ">
+                                <View className="items-center justify-center pt-4 space-y-2 ">
+                                    <Image
+                                        source={require('../../assets/car1.png')}
+                                        style={{ height: 72, width: 140 }}
+                                    />
+
+                                    <Text className="text-base text-[#222222]">
+                                        TESLA - Model 3
+                                    </Text>
+                                </View>
+                            </View>
+                        </ScrollView>
+                    </View>
+                </View>
+
+                <View className="h-[20vh] mx-[5%]">
+                    <View className="flex-1 justify-center">
+                        <Pressable
+                            style={{ alignSelf: 'flex-start' }}
+                            onPress={() => console.log('選擇充電方案')}
+                        >
+                            <Text className="text-lg" style={styles.grayColor}>
+                                選擇充電方案
+                            </Text>
+                        </Pressable>
+                    </View>
+                    <View className="flex-1 justify-center">
+                        <Pressable
+                            style={{ alignSelf: 'flex-start' }}
+                            onPress={() => console.log('選擇日期時間')}
+                        >
+                            <Text className="text-lg" style={styles.grayColor}>
+                                選擇日期時間
+                            </Text>
+                        </Pressable>
+                    </View>
+
+                    <View className="flex-1  justify-center">
+                        <Pressable
+                            style={{ alignSelf: 'flex-start' }}
+                            onPress={() => console.log('選擇充電座')}
+                        >
+                            <Text className="text-lg" style={styles.grayColor}>
+                                選擇充電座
+                            </Text>
+                        </Pressable>
+                    </View>
+                </View>
+            </View>
+
+            <View className="h-[50vh] bg-white mx-[5%]">
+                <View
+                    className="flex-1 flex-row max-h-[100px] border-slate-300 my-6 rounded-2xl"
+                    style={{ borderWidth: 1 }}
+                >
+                    <View className="flex-1 m-4">
+                        <View className="flex-1 flex-row ">
+                            <View className=" flex-1 flex-column  justify-between">
+                                <Text className="text-xl " style={styles.text}>
+                                    收費
+                                </Text>
+
+                                <View className="flex-row items-center space-x-2">
+                                    <Text className="text-3xl text-[#02677D]">
+                                        $20
+                                    </Text>
+                                    <Text style={styles.text}>每15分鐘</Text>
+                                </View>
+                            </View>
+                            <View className="items-center justify-center">
+                                <View className="w-[1px] h-[60%] bg-[#CCCCCC]" />
+                            </View>
+                            <View className="flex-1 flex-column ">
+                                <View className="flex-1"></View>
+                                <View className="flex-row items-center ml-4 space-x-2 ">
+                                    <Text className="text-3xl text-[#02677D]">
+                                        $3.5
+                                    </Text>
+                                    <Text style={styles.text}>每度電</Text>
+                                </View>
+                            </View>
+                        </View>
+                    </View>
+                </View>
+
+                <Text className="text-xl pb-2 mx-[5%]" style={styles.text}>
+                    充電站資訊
+                </Text>
+                <ChargingStationTabView titles={['充電插頭', '其他']} />
+            </View>
+        </ScrollView>
+    </SafeAreaView>
+);
+
+export default MakingBookingPage;
+
+const styles = StyleSheet.create({
+    grayColor: {
+        color: '#888888'
+    },
+    topLeftTriangle: {
+        width: 0,
+        height: 0,
+        borderLeftWidth: 50,
+        borderBottomWidth: 50,
+        borderLeftColor: '#02677D',
+        borderBottomColor: 'transparent',
+        position: 'absolute',
+        top: 0,
+        left: 0
+    },
+    text: {
+        fontWeight: 300,
+        color: '#000000'
+    }
+});

+ 316 - 0
component/reservationLocationPage/reservationLocationPage.tsx

@@ -0,0 +1,316 @@
+import Svg, { Path, Rect } from 'react-native-svg';
+import * as React from 'react';
+import {
+    View,
+    Text,
+    useWindowDimensions,
+    StyleSheet,
+    Image,
+    ImageSourcePropType,
+    Pressable
+} from 'react-native';
+import { TabView, SceneMap, TabBar } from 'react-native-tab-view';
+import { FlashList } from '@shopify/flash-list';
+import { SafeAreaView } from 'react-native-safe-area-context';
+import NormalInput from '../global/normal_input';
+import { router } from 'expo-router';
+
+export interface TabItem {
+    imgURL: ImageSourcePropType;
+    date: string;
+    time: string;
+    chargeStationName: string;
+    chargeStationAddress: string;
+    distance: string;
+}
+
+interface TabViewComponentProps {
+    titles: string[];
+    tabItems: TabItem[];
+}
+
+const CheckMarkLogoSvg = () => (
+    <Svg width="20" height="20" viewBox="0 0 20 20" fill="none">
+        <Rect width="20" height="20" rx="10" fill="#02677D" />
+        <Path
+            d="M7.95837 15L3.20837 10.25L4.39587 9.06251L7.95837 12.625L15.6042 4.97917L16.7917 6.16667L7.95837 15Z"
+            fill="white"
+        />
+    </Svg>
+);
+
+const dummyTabItems: TabItem[] = [
+    {
+        imgURL: require('../../assets/dummyStationPicture.png'),
+        date: '今天',
+        time: '16:30',
+        chargeStationName: '上環街市充電站',
+        chargeStationAddress: '香港上環皇后大道中345號',
+        distance: '400米'
+    },
+    {
+        imgURL: require('../../assets/dummyStationPicture2.png'),
+        date: '3月15',
+        time: '17:45',
+        chargeStationName: '中環IFC充電站',
+        chargeStationAddress: '香港中環皇后大道中999號',
+        distance: '680米'
+    },
+    {
+        imgURL: require('../../assets/dummyStationPicture2.png'),
+        date: '4月20',
+        time: '12:30',
+        chargeStationName: '中環IFC充電站',
+        chargeStationAddress: '香港中環皇后大道中999號',
+        distance: '680米'
+    },
+    {
+        imgURL: require('../../assets/dummyStationPicture.png'),
+        date: '今天',
+        time: '16:30',
+        chargeStationName: '上環街市充電站',
+        chargeStationAddress: '香港上環皇后大道中345號',
+        distance: '400米'
+    },
+    {
+        imgURL: require('../../assets/dummyStationPicture.png'),
+        date: '今天',
+        time: '16:30',
+        chargeStationName: '上環街市充電站',
+        chargeStationAddress: '香港上環皇后大道中345號',
+        distance: '400米'
+    }
+];
+
+const LocationTabComponent: React.FC<TabViewComponentProps> = ({
+    titles,
+    tabItems
+}) => {
+    const layout = useWindowDimensions();
+
+    const FirstRoute = () => (
+        <View style={{ flex: 1, backgroundColor: 'white' }}>
+            <FlashList
+                data={tabItems}
+                renderItem={({ item }) => {
+                    return (
+                        <View style={styles.container}>
+                            <Image style={styles.image} source={item.imgURL} />
+                            <View style={styles.textContainer}>
+                                <Text
+                                    style={{
+                                        fontWeight: 400,
+                                        fontSize: 18,
+                                        color: '#222222'
+                                    }}
+                                >
+                                    {item.chargeStationName}
+                                </Text>
+                                <Text
+                                    style={{
+                                        fontWeight: 400,
+                                        fontSize: 14,
+                                        color: '#888888'
+                                    }}
+                                >
+                                    {item.chargeStationAddress}
+                                </Text>
+                                <View className=" flex-row space-x-2  items-center">
+                                    <CheckMarkLogoSvg />
+                                    <Text
+                                        style={{
+                                            fontWeight: 400,
+                                            fontSize: 14,
+                                            color: '#222222'
+                                        }}
+                                    >
+                                        Walk-in
+                                    </Text>
+                                </View>
+                            </View>
+                            <Text
+                                style={{
+                                    fontWeight: 400,
+                                    fontSize: 16,
+                                    color: '#888888',
+                                    marginTop: 22
+                                }}
+                            >
+                                {item.distance}
+                            </Text>
+                        </View>
+                    );
+                }}
+                estimatedItemSize={10}
+            />
+        </View>
+    );
+
+    //tab 2
+    const SecondRoute = () => (
+        <View style={{ flex: 1, backgroundColor: 'white' }}>
+            <FlashList
+                data={tabItems}
+                renderItem={({ item }) => {
+                    return (
+                        <View style={styles.container}>
+                            <Image style={styles.image} source={item.imgURL} />
+                            <View style={styles.textContainer}>
+                                <Text
+                                    style={{
+                                        fontWeight: 400,
+                                        fontSize: 18,
+                                        color: '#222222'
+                                    }}
+                                >
+                                    {item.chargeStationName}
+                                </Text>
+                                <Text
+                                    style={{
+                                        fontWeight: 400,
+                                        fontSize: 14,
+                                        color: '#888888'
+                                    }}
+                                >
+                                    {item.chargeStationAddress}
+                                </Text>
+                                <View className=" flex-row space-x-2 items-center">
+                                    <CheckMarkLogoSvg />
+                                    <Text
+                                        style={{
+                                            fontWeight: 400,
+                                            fontSize: 14,
+                                            color: '#222222'
+                                        }}
+                                    >
+                                        Walk-in
+                                    </Text>
+                                </View>
+                            </View>
+                            <Text
+                                style={{
+                                    fontWeight: 400,
+                                    fontSize: 16,
+                                    color: '#888888',
+                                    marginTop: 22
+                                }}
+                            >
+                                {item.distance}
+                            </Text>
+                        </View>
+                    );
+                }}
+                estimatedItemSize={10}
+            />
+        </View>
+    );
+
+    const renderScene = SceneMap({
+        firstRoute: FirstRoute,
+        secondRoute: SecondRoute
+    });
+    const [routes] = React.useState([
+        { key: 'firstRoute', title: titles[0] },
+        { key: 'secondRoute', title: titles[1] }
+    ]);
+    const [index, setIndex] = React.useState(0);
+
+    const renderTabBar = (props: any) => (
+        <TabBar
+            {...props}
+            renderLabel={({ route, focused }) => (
+                <Text
+                    style={{
+                        color: focused ? '#025c72' : '#888888',
+                        fontWeight: focused ? '900' : 'thin',
+                        fontSize: 20
+                    }}
+                >
+                    {route.title}
+                </Text>
+            )}
+            indicatorStyle={{
+                backgroundColor: '#025c72'
+            }}
+            style={{
+                backgroundColor: 'white',
+                borderColor: '#DBE4E8',
+                elevation: 0,
+                marginHorizontal: 15,
+                borderBottomWidth: 0.5
+            }}
+        />
+    );
+    return (
+        <TabView
+            navigationState={{ index, routes }}
+            renderScene={renderScene}
+            onIndexChange={setIndex}
+            initialLayout={{ width: layout.width }}
+            renderTabBar={renderTabBar}
+        />
+    );
+};
+
+const styles = StyleSheet.create({
+    container: { flexDirection: 'row' },
+    image: { width: 100, height: 100, margin: 15, borderRadius: 10 },
+    textContainer: { flexDirection: 'column', gap: 8, marginTop: 22 }
+});
+
+const ReservationLocationPage = () => {
+    const CrossLogoSvg = () => (
+        <Svg width="24" height="24" viewBox="0 0 24 24" fill="none">
+            <Path
+                d="M2.33333 23.3333L0 21L9.33333 11.6667L0 2.33333L2.33333 0L11.6667 9.33333L21 0L23.3333 2.33333L14 11.6667L23.3333 21L21 23.3333L11.6667 14L2.33333 23.3333Z"
+                fill="#222222"
+            />
+        </Svg>
+    );
+
+    return (
+        <SafeAreaView className="flex-1 bg-white">
+            <View className="flex-1 mx-[5%]">
+                <View className="min-h-[250px] flex-column">
+                    <View className="flex-2 justify-center ">
+                        <View className="pt-6 ">
+                            {/* For now, clicking the X button goes back to login page. */}
+                            {/* Once home page component is created, i will change it */}
+                            <Pressable
+                                onPress={() => {
+                                    if (router.canGoBack()) {
+                                        router.back();
+                                    } else {
+                                        router.replace('/');
+                                    }
+                                }}
+                            >
+                                <CrossLogoSvg />
+                            </Pressable>
+                        </View>
+                    </View>
+                    <View className="flex-1 justify-center ">
+                        <Text className="text-[50px] font-normal">
+                            預約地點
+                        </Text>
+                    </View>
+                    <View className="flex-1 justify-center mb-6 ">
+                        <NormalInput
+                            placeholder="搜尋所有充電站或地區.."
+                            onChangeText={() => console.log('input')}
+                            extendedStyle={{ padding: 20 }}
+                        />
+                    </View>
+                </View>
+                <View className="flex-1">
+                    <LocationTabComponent
+                        titles={['附近的充電站', '所有的充電站']}
+                        tabItems={dummyTabItems}
+                    />
+                </View>
+            </View>
+        </SafeAreaView>
+    );
+};
+
+export default ReservationLocationPage;

+ 202 - 0
component/searchPage/searchPage.tsx

@@ -0,0 +1,202 @@
+import { ScrollView, Text, View, StyleSheet, Pressable } from 'react-native';
+import NormalInput from '../global/normal_input';
+import Svg, { Path } from 'react-native-svg';
+
+import NormalButton from '../global/normal_button';
+import { FlashList } from '@shopify/flash-list';
+
+interface BookingHistory {
+    charingStationName: string;
+    chargingStationAddress: string;
+}
+
+interface SearchPageProps {}
+
+const ArrowIconSvg = () => (
+    <Svg width="8" height="12" viewBox="0 0 8 12" fill="none">
+        <Path
+            d="M0.6 6L6.6 -6.11959e-08L8 1.4L3.4 6L8 10.6L6.6 12L0.6 6Z"
+            fill="#888888"
+        />
+    </Svg>
+);
+
+const bookingHistoryData: BookingHistory[] = [
+    {
+        charingStationName: '充電站#1',
+        chargingStationAddress: '充電站地址#1'
+    },
+    {
+        charingStationName: '充電站#2',
+        chargingStationAddress: '充電站地址#2'
+    },
+    {
+        charingStationName: '充電站#3',
+        chargingStationAddress: '充電站地址#3'
+    },
+    {
+        charingStationName: '充電站#4',
+        chargingStationAddress: '充電站地址#4'
+    }
+];
+
+const SearchPage: React.FC<SearchPageProps> = () => {
+    return (
+        <ScrollView className="bg-[#ffffff] flex-1 h-[100vh] px-[5%] pt-[5%] ">
+            <View className="flex-column gap-4 ">
+                <View className=" flex-1 flex-row ">
+                    <Pressable
+                        style={styles.leftArrowBackButton}
+                        onPress={() => console.log('Back Button')}
+                    >
+                        <ArrowIconSvg />
+                    </Pressable>
+                    <NormalInput
+                        placeholder="搜尋這裡"
+                        onChangeText={(abc) => console.log(abc)}
+                        extendedStyle={styles.textInput}
+                    />
+                </View>
+                <ScrollView
+                    horizontal={true}
+                    className="space-x-4"
+                    showsHorizontalScrollIndicator={false}
+                >
+                    <View>
+                        <NormalButton
+                            title={
+                                <Text style={{ color: '#061E25' }}>
+                                    附近的充電站
+                                </Text>
+                            }
+                            onPress={() => console.log('附近的充電站')}
+                            buttonPressedStyle={{
+                                backgroundColor: '#CFDEE4'
+                            }}
+                            extendedStyle={{
+                                backgroundColor: '#E3F2F8',
+                                borderRadius: 8,
+                                paddingVertical: 12
+                            }}
+                        />
+                    </View>
+                    <View>
+                        <NormalButton
+                            title={
+                                <Text style={{ color: '#061E25' }}>
+                                    可Walk-in的充電站
+                                </Text>
+                            }
+                            onPress={() => console.log('可Walk-in的充電站')}
+                            buttonPressedStyle={{
+                                backgroundColor: '#CFDEE4'
+                            }}
+                            extendedStyle={{
+                                backgroundColor: '#E3F2F8',
+                                borderRadius: 8,
+                                paddingVertical: 12
+                            }}
+                        />
+                    </View>
+                    <View>
+                        <NormalButton
+                            title={
+                                <Text style={{ color: '#061E25' }}>
+                                    Test Tab #1
+                                </Text>
+                            }
+                            onPress={() => console.log('Test Tab #1')}
+                            buttonPressedStyle={{
+                                backgroundColor: '#CFDEE4'
+                            }}
+                            extendedStyle={{
+                                backgroundColor: '#E3F2F8',
+                                borderRadius: 8,
+                                paddingVertical: 12
+                            }}
+                        />
+                    </View>
+                    <View>
+                        <NormalButton
+                            title={
+                                <Text style={{ color: '#061E25' }}>
+                                    Test Tab #2
+                                </Text>
+                            }
+                            onPress={() => console.log('Test Tab #2')}
+                            buttonPressedStyle={{
+                                backgroundColor: '#CFDEE4'
+                            }}
+                            extendedStyle={{
+                                backgroundColor: '#E3F2F8',
+                                borderRadius: 8,
+                                paddingVertical: 12
+                            }}
+                        />
+                    </View>
+                </ScrollView>
+                <View>
+                    <Text
+                        style={{
+                            fontWeight: 400,
+                            fontSize: 16,
+                            color: '#222222',
+                            paddingTop: 6
+                        }}
+                    >
+                        預約記錄
+                    </Text>
+                    <FlashList
+                        estimatedItemSize={10}
+                        data={bookingHistoryData}
+                        renderItem={({ item }) => (
+                            <View className="flex-column space-y-1 py-4 border-b border-gray-300">
+                                <Text className="text-base text-[#222222]">
+                                    {item.charingStationName}
+                                </Text>
+                                <Text className="text-base text-[#888888]">
+                                    {item.chargingStationAddress}
+                                </Text>
+                            </View>
+                        )}
+                    />
+                </View>
+            </View>
+        </ScrollView>
+    );
+};
+
+export default SearchPage;
+
+const styles = StyleSheet.create({
+    leftArrowBackButton: {
+        width: '15%',
+        maxWidth: '100%',
+        fontSize: 16,
+        padding: 20,
+        paddingLeft: 30,
+        borderBottomLeftRadius: 12,
+        borderTopLeftRadius: 12,
+        borderColor: '#bbbbbb',
+        borderTopWidth: 1,
+        borderBottomWidth: 1,
+        borderLeftWidth: 1,
+        alignItems: 'center',
+        justifyContent: 'center'
+    },
+    textInput: {
+        width: '85%',
+        maxWidth: '100%',
+        fontSize: 16,
+        padding: 20,
+        paddingLeft: 0,
+        borderLeftWidth: 0,
+        borderTopWidth: 1,
+        borderBottomWidth: 1,
+        borderRightWidth: 1,
+        borderBottomRightRadius: 12,
+        borderTopRightRadius: 12,
+        borderRadius: 0,
+        borderColor: '#bbbbbb'
+    }
+});

+ 1 - 1
factory-env

@@ -1 +1 @@
-Subproject commit 7aa5242810d13ba08fe44e24a4579d740ff2c110
+Subproject commit 60576453748740871f1e34e67282bd87721373fc