Sfoglia il codice sorgente

made charging page component

Ian Fung 1 anno fa
parent
commit
e01b3347d5

BIN
assets/car.png


+ 221 - 0
component/chargingPage/chargingPage.tsx

@@ -0,0 +1,221 @@
+import { View, Text, ScrollView, StyleSheet, Image } from 'react-native';
+import { SafeAreaView } from 'react-native-safe-area-context';
+import Svg, { Path } from 'react-native-svg';
+import RippleEffectBatteryIcon from '../global/rippleEffectBatteryIcon';
+import LoadingDots from '../global/loadingDots';
+import NormalButton from '../global/normal_button';
+
+const LightingLogoSvg = () => (
+    <Svg width="21" height="30" viewBox="0 0 21 30" fill="none">
+        <Path
+            d="M5.75631 29.8077L7.42297 18.3333H0.3396L12.8076 0.352539H13.5768L11.9422 13.3333H20.2756L6.52552 29.8077H5.75631Z"
+            fill="#02677D"
+        />
+    </Svg>
+);
+
+const BatteryIconSvg = () => (
+    <Svg width="20" height="31" viewBox="0 0 20 31" fill="none">
+        <Path
+            d="M15.1282 30.8013V26.4103H12.5641L16.5384 19.1987V23.5898H19.1026L15.1282 30.8013ZM1.98716 30C1.60574 30 1.28603 29.871 1.02803 29.613C0.770005 29.355 0.640991 29.0353 0.640991 28.6539V3.81408C0.640991 3.4327 0.770005 3.11299 1.02803 2.85496C1.28603 2.59696 1.60574 2.46796 1.98716 2.46796H4.67949V0H10.3205V2.46796H13.0194C13.4018 2.46796 13.7206 2.59696 13.9759 2.85496C14.2313 3.11299 14.359 3.4327 14.359 3.81408V15.3205C11.9872 15.6261 9.99466 16.68 8.38141 18.4824C6.76816 20.2847 5.96153 22.4252 5.96153 24.9038C5.96153 25.8398 6.0876 26.7383 6.33974 27.5994C6.59188 28.4605 6.96046 29.2607 7.44549 30H1.98716Z"
+            fill="#02677D"
+        />
+    </Svg>
+);
+
+const TemperatureIconSvg = () => (
+    <Svg width="15" height="30" viewBox="0 0 15 30" fill="none">
+        <Path
+            d="M7.50004 30C5.64321 30 4.06789 29.3531 2.77408 28.0593C1.48028 26.7655 0.833374 25.1902 0.833374 23.3333C0.833374 22.1282 1.13037 21.0187 1.72437 20.0048C2.3184 18.9909 3.13251 18.1773 4.16671 17.5641V3.33333C4.16671 2.39317 4.48722 1.60257 5.12825 0.961543C5.76928 0.320515 6.55987 0 7.50004 0C8.44021 0 9.2308 0.320515 9.87183 0.961543C10.5129 1.60257 10.8334 2.39317 10.8334 3.33333V17.5641C11.8676 18.1773 12.6817 18.9909 13.2757 20.0048C13.8697 21.0187 14.1667 22.1282 14.1667 23.3333C14.1667 25.1902 13.5198 26.7655 12.226 28.0593C10.9322 29.3531 9.35687 30 7.50004 30ZM5.83337 13.9744H9.16671V11.4744H7.50004V10.1923H9.16671V6.47438H7.50004V5.19229H9.16671V3.33333C9.16671 2.86111 9.00698 2.46528 8.68754 2.14583C8.3681 1.82639 7.97226 1.66667 7.50004 1.66667C7.02782 1.66667 6.63198 1.82639 6.31254 2.14583C5.9931 2.46528 5.83337 2.86111 5.83337 3.33333V13.9744Z"
+            fill="#02677D"
+        />
+    </Svg>
+);
+
+const ChargingPage = () => {
+    return (
+        <SafeAreaView
+            style={{ flex: 1, backgroundColor: 'white' }}
+            edges={['top', 'left', 'right']}
+        >
+            <ScrollView className="flex-1">
+                <View className="h-[130vh] mx-[5%] space-y-4">
+                    <View className="items-center">
+                        <View className="mt-6 mb-4">
+                            <Text className="text-lg ">現正充電中:</Text>
+                        </View>
+                        <Text className="text-4xl font-light">
+                            TESLA Model 3
+                        </Text>
+                    </View>
+                    <View className="items-center">
+                        <Text className="text-lg" style={styles.grayColor}>
+                            充電中
+                        </Text>
+                        <View className="flex-row space-x-4 p-4 pr-8 items-center">
+                            <RippleEffectBatteryIcon />
+                            <Text
+                                style={{
+                                    color: '#02677D',
+                                    fontSize: 60,
+                                    fontWeight: 300
+                                }}
+                            >
+                                55%
+                                <LoadingDots />
+                            </Text>
+                        </View>
+                        <Text className="text-lg mb-6" style={styles.grayColor}>
+                            尚餘時間 ~48 mins
+                        </Text>
+                        <View className="mb-[-10] items-center justify-center ">
+                            <Image
+                                source={require('../../assets/car1.png')}
+                                style={{ width: 430, height: 200 }}
+                                resizeMode="contain"
+                            />
+                        </View>
+                    </View>
+                    <View
+                        className="h-[220px] min-h-[20px] border-slate-300 rounded-2xl flex-column"
+                        style={{ borderWidth: 1 }}
+                    >
+                        {/* Top */}
+                        <View className="h-[65%] flex-row justify-evenly items-center">
+                            <View className="flex-1 flex-column items-center space-y-2">
+                                <LightingLogoSvg />
+                                <Text
+                                    style={styles.grayColor}
+                                    className="text-base"
+                                >
+                                    充電功率
+                                </Text>
+                                <Text
+                                    style={styles.greenColor}
+                                    className="font-bold text-base"
+                                >
+                                    22.1kW
+                                </Text>
+                            </View>
+                            <View className="flex-1 flex-column items-center space-y-2">
+                                <BatteryIconSvg />
+                                <Text
+                                    style={styles.grayColor}
+                                    className="text-base"
+                                >
+                                    實際功率
+                                </Text>
+                                <Text
+                                    style={styles.greenColor}
+                                    className="font-bold text-base"
+                                >
+                                    30.0kW
+                                </Text>
+                            </View>
+                            <View className="flex-1 flex-column items-center space-y-2">
+                                <TemperatureIconSvg />
+                                <Text
+                                    style={styles.grayColor}
+                                    className="text-base"
+                                >
+                                    溫度
+                                </Text>
+                                <Text
+                                    style={styles.greenColor}
+                                    className="font-bold text-base"
+                                >
+                                    36°c
+                                </Text>
+                            </View>
+                        </View>
+                        <View className="mx-[5%]">
+                            <View className="h-[1px] w-[100%] bg-[#CCCCCC]" />
+                        </View>
+                        {/* bottom container */}
+                        <View className="h-[35%] mx-[5%] justify-center ">
+                            <Text
+                                style={styles.grayColor}
+                                className="text-base"
+                            >
+                                充電歷時 ~12mins
+                            </Text>
+                        </View>
+                    </View>
+                    <View
+                        className="h-[8%] min-h-[20px] border-slate-300 rounded-2xl justify-center"
+                        style={{ borderWidth: 1 }}
+                    >
+                        <View className="mx-[5%] flex-row items-center justify-between">
+                            <View>
+                                <Text className="text-lg">預計充電費用</Text>
+
+                                <Text
+                                    className="text-base"
+                                    style={styles.grayColor}
+                                >
+                                    按每度電結算: 50 kWh
+                                </Text>
+                            </View>
+                            <Text className="text-3xl">HK$ 175</Text>
+                        </View>
+                    </View>
+                    <View
+                        className="h-[10%]  border-slate-300 rounded-2xl justify-center pl-4"
+                        style={{ borderWidth: 1 }}
+                    >
+                        <Text className="text-lg ">其他資訊</Text>
+                        <View className="flex-row">
+                            <View className="flex-1 flex-column">
+                                <Text
+                                    className="text-base"
+                                    style={styles.grayColor}
+                                >
+                                    開始時間
+                                </Text>
+                                <Text className="text-base">16:33:04</Text>
+                            </View>
+                            <View className="flex-1 flex-column">
+                                <Text
+                                    className="text-base"
+                                    style={styles.grayColor}
+                                >
+                                    充電座
+                                </Text>
+                                <Text className="text-base">A104</Text>
+                            </View>
+                        </View>
+                    </View>
+                    <View className="w-full ">
+                        <NormalButton
+                            onPress={() => {
+                                console.log('完成充電');
+                            }}
+                            title={
+                                <Text
+                                    className="text-xl text-white"
+                                    style={{ fontWeight: 900 }}
+                                >
+                                    完成充電
+                                </Text>
+                            }
+                        />
+                    </View>
+                </View>
+            </ScrollView>
+        </SafeAreaView>
+    );
+};
+
+export default ChargingPage;
+const styles = StyleSheet.create({
+    grayColor: {
+        color: '#888888'
+    },
+    greenColor: {
+        color: '#02677D'
+    },
+    text: {
+        fontWeight: 300,
+        color: '#000000'
+    }
+});

+ 71 - 0
component/global/loadingDots.tsx

@@ -0,0 +1,71 @@
+import { useEffect, useRef } from 'react';
+import { View, Animated, StyleSheet } from 'react-native';
+
+const LoadingDots = () => {
+    const fadeAnim1 = useRef(new Animated.Value(1)).current;
+    const fadeAnim2 = useRef(new Animated.Value(0)).current;
+    const fadeAnim3 = useRef(new Animated.Value(0)).current;
+    useEffect(() => {
+        const animateSequence = () => {
+            Animated.sequence([
+                Animated.timing(fadeAnim1, {
+                    toValue: 1,
+                    duration: 500,
+                    useNativeDriver: true
+                }),
+                Animated.timing(fadeAnim1, {
+                    toValue: 0,
+                    duration: 0,
+                    useNativeDriver: true
+                }),
+                Animated.timing(fadeAnim2, {
+                    toValue: 1,
+                    duration: 500,
+                    useNativeDriver: true
+                }),
+                Animated.timing(fadeAnim2, {
+                    toValue: 0,
+                    duration: 0,
+                    useNativeDriver: true
+                }),
+                Animated.timing(fadeAnim3, {
+                    toValue: 1,
+                    duration: 500,
+                    useNativeDriver: true
+                }),
+                Animated.timing(fadeAnim3, {
+                    toValue: 0,
+                    duration: 0,
+                    useNativeDriver: true
+                })
+            ]).start(() => {
+                animateSequence();
+            });
+        };
+
+        animateSequence();
+    }, [fadeAnim1, fadeAnim2, fadeAnim3]);
+
+    return (
+        <View className="flex-row items-center">
+            <Animated.Text style={[styles.text, { opacity: fadeAnim1 }]}>
+                .
+            </Animated.Text>
+            <Animated.Text style={[styles.text, { opacity: fadeAnim2 }]}>
+                .
+            </Animated.Text>
+            <Animated.Text style={[styles.text, { opacity: fadeAnim3 }]}>
+                .
+            </Animated.Text>
+        </View>
+    );
+};
+
+const styles = StyleSheet.create({
+    text: {
+        fontSize: 16,
+        color: '#02677D'
+    }
+});
+
+export default LoadingDots;

+ 78 - 0
component/global/rippleEffectBatteryIcon.tsx

@@ -0,0 +1,78 @@
+import { useEffect } from 'react';
+import { StyleSheet, View } from 'react-native';
+import { widthPercentageToDP as wp } from 'react-native-responsive-screen';
+import Animated, {
+    useAnimatedStyle,
+    useSharedValue,
+    withRepeat,
+    withTiming
+} from 'react-native-reanimated';
+import Svg, { Path, Rect } from 'react-native-svg';
+
+const BatterySvg = () => (
+    <Svg width="40" height="40" viewBox="0 0 40 40" fill="none">
+        <Rect width="40" height="40" rx="20" fill="#02677D" />
+        <Path
+            d="M25.1202 32.2255V28.7039H22.5962L26.274 22.8746V26.3962H28.798L25.1202 32.2255ZM14.8798 31.925C14.5597 31.925 14.2914 31.8168 14.0748 31.6002C13.8583 31.3837 13.75 31.1153 13.75 30.7952V11.4804C13.75 11.1603 13.8583 10.8919 14.0748 10.6754C14.2914 10.4589 14.5597 10.3506 14.8798 10.3506H17.1394V8.17511H21.7547V10.3506H24.0168C24.3373 10.3506 24.6053 10.4589 24.8208 10.6754C25.0364 10.8919 25.1441 11.1603 25.1441 11.4804V20.1703C24.8108 20.1863 24.4899 20.2228 24.1814 20.2796C23.8729 20.3365 23.5689 20.4179 23.2692 20.5236V12.2135H15.6249V27.514H18.2452C18.2452 28.3441 18.3758 29.1342 18.637 29.8842C18.8982 30.6342 19.2708 31.3145 19.7547 31.925H14.8798Z"
+            fill="#FAFAFA"
+        />
+    </Svg>
+);
+
+const RippleEffectBatteryIcon = () => {
+    const scaleValue = useSharedValue(1);
+    const opacityValue = useSharedValue(1);
+    const textScaleValue = useSharedValue(0.4);
+
+    const animatedCircle = useAnimatedStyle(() => {
+        return {
+            transform: [{ scale: scaleValue.value }],
+            opacity: opacityValue.value
+        };
+    });
+
+    const startRippleAnimation = () => {
+        scaleValue.value = withRepeat(withTiming(3, { duration: 2000 }), -1);
+        opacityValue.value = withRepeat(withTiming(0, { duration: 2000 }), -1);
+        textScaleValue.value = withRepeat(
+            withTiming(1, { duration: 10000 }),
+            -1
+        );
+    };
+
+    useEffect(() => {
+        startRippleAnimation();
+    }, []);
+
+    return (
+        <View className="relative">
+            <View className="absolute">
+                <BatterySvg></BatterySvg>
+            </View>
+            <View style={{ width: 40, height: 40 }}>
+                <Animated.View
+                    style={[animatedCircle, styles.innerCircle]}
+                ></Animated.View>
+            </View>
+        </View>
+    );
+};
+
+export default RippleEffectBatteryIcon;
+
+const styles = StyleSheet.create({
+    innerCircle: {
+        width: '100%',
+        height: '100%',
+        borderRadius: 200,
+        backgroundColor: '#025c72',
+        justifyContent: 'center'
+    },
+    innerText: {
+        fontSize: 14,
+        alignSelf: 'center',
+        fontWeight: 'bold',
+        position: 'absolute',
+        top: wp(10)
+    }
+});