Projekt

Obecné

Profil

« Předchozí | Další » 

Revize c8be2597

Přidáno uživatelem Fantič před více než 1 rok

re #10818 Vývoj Toast info/error: basic components style

Zobrazit rozdíly:

src/components/toast/ErrorToast.tsx
1

  
2
import React from 'react';
3
import { HStack, CircleIcon, View, ScrollView, Button, Center, Heading, Pressable, Text, Box, Container, VStack, Icon, ArrowBackIcon, ChevronLeftIcon, ChevronRightIcon, useToast, Alert, IconButton, CloseIcon, Spacer } from "native-base";
4

  
5

  
6
interface ErrorToastProps {
7
    headerText?: string
8
    text: string
9
    onClose: () => void
10
}
11

  
12
export const ErrorToast = (props: ErrorToastProps) => {
13

  
14
    const { text, headerText, onClose } = props;
15

  
16
    return (
17
        <Alert
18
            alignSelf="center"
19
            flexDirection="row"
20
            variant="outline"
21
            status="warning"
22
            backgroundColor={"error.50"}
23
        >
24
            <VStack>
25
                <HStack space={2} flexShrink={1} alignItems="center">
26
                    <Alert.Icon size="xs" />
27
                    {headerText ?
28
                        <Text fontSize="sm" fontWeight="medium" color="error.700">
29
                            {headerText}
30
                        </Text> :
31
                        <Text fontSize="xs" color="error.500">
32
                            {text}
33
                        </Text>}
34
                    <Spacer />
35
                    <IconButton
36
                        variant="unstyled"
37
                        icon={<CloseIcon size="3" color="error.500" />}
38
                        onPress={() => {
39
                            onClose();
40
                        }}
41
                    />
42
                </HStack>
43
                {headerText &&
44
                    <Text fontSize="xs" color="error.500">
45
                        {text}
46
                    </Text>}
47
            </VStack>
48
        </Alert>
49
    )
50
}
51

  
src/components/toast/InfoToast.tsx
1

  
2
import React from 'react';
3
import { HStack, CircleIcon, View, ScrollView, Button, Center, Heading, Pressable, Text, Box, Container, VStack, Icon, ArrowBackIcon, ChevronLeftIcon, ChevronRightIcon, useToast, Alert, IconButton, CloseIcon, Spacer } from "native-base";
4

  
5
interface InfoToastProps {
6
    headerText?: string
7
    text: string
8
    onClose: () => void
9
}
10

  
11
export const InfoToast = (props: InfoToastProps) => {
12

  
13
    const { text, headerText, onClose } = props;
14

  
15
    return (
16
        <Alert
17
            alignSelf="center"
18
            flexDirection="row"
19
            variant="outline"
20
            status="info"
21
            backgroundColor={"info.50"}
22
        >
23
            <VStack>
24
                <HStack space={2} flexShrink={1} alignItems="center">
25
                    <Alert.Icon size="xs" />
26
                    {headerText ?
27
                        <Text fontSize="sm" fontWeight="medium" color="info.700">
28
                            {headerText}
29
                        </Text> :
30
                        <Text fontSize="xs" color="info.500">
31
                            {text}
32
                        </Text>}
33
                    <Spacer />
34
                    <IconButton
35
                        variant="unstyled"
36
                        icon={<CloseIcon size="3" color="info.500" />}
37
                        onPress={() => {
38
                            onClose();
39
                        }}
40
                    />
41
                </HStack>
42
                {headerText &&
43
                    <Text fontSize="xs" color="info.500">
44
                        {text}
45
                    </Text>}
46
            </VStack>
47
        </Alert>
48
    )
49
};
50

  
src/components/toast/SuccessToast.tsx
1

  
2
import React from 'react';
3
import { HStack, CircleIcon, View, ScrollView, Button, Center, Heading, Pressable, Text, Box, Container, VStack, Icon, ArrowBackIcon, ChevronLeftIcon, ChevronRightIcon, useToast, Alert, IconButton, CloseIcon, Spacer } from "native-base";
4

  
5

  
6
interface SuccessToastProps {
7
    headerText?: string
8
    text: string
9
    onClose: () => void
10
}
11

  
12
export const SuccessToast = (props: SuccessToastProps) => {
13

  
14
    const { text, headerText, onClose } = props;
15

  
16
    return (
17
        <Alert
18
            alignSelf="center"
19
            flexDirection="row"
20
            variant="outline"
21
            status="success"
22
            backgroundColor={"success.50"}
23
        >
24
            <VStack>
25
                <HStack space={2} flexShrink={1} alignItems="center">
26
                    <Alert.Icon size="xs" />
27
                    {headerText ?
28
                        <Text fontSize="sm" fontWeight="medium" color="success.700">
29
                            {headerText}
30
                        </Text> :
31
                        <Text fontSize="xs" color="success.500">
32
                            {text}
33
                        </Text>}
34
                    <Spacer />
35
                    <IconButton
36
                        variant="unstyled"
37
                        icon={<CloseIcon size="3" color="success.500" />}
38
                        onPress={() => {
39
                            onClose();
40
                        }}
41
                    />
42
                </HStack>
43
                {headerText &&
44
                    <Text fontSize="xs" color="success.500">
45
                        {text}
46
                    </Text>}
47
            </VStack>
48
        </Alert>
49
    )
50
};
51

  
src/pages/HomePage.tsx
1 1
import { Center, Image, Pressable, ScrollView, Text } from "native-base"
2 2
import { useDispatch, useSelector } from "react-redux"
3 3
import { AppDispatch, RootState } from "../stores/store"
4
import { useEffect, useState } from "react"
4
import { useContext, useEffect, useState } from "react"
5 5
import { fetchData } from "../stores/actions/homePageThunks"
6 6
import { ApplicationHeading } from "../components/reusables/ApplicationHeading"
7 7
import LoadingBox from "../components/loading/LoadingBox"
......
14 14
const HomePage = ({navigation}: DrawerScreenProps<RootDrawerParamList, 'Home'>) => {
15 15
    const data = useSelector((state: RootState) => state.homePage.data)
16 16
    const loading = useSelector((state: RootState) => state.homePage.loading)
17
    const error = useSelector((state: RootState) => state.homePage.lastError)
17
    const lastError = useSelector((state: RootState) => state.homePage.lastError)
18

  
19
    useEffect(() => {
20
        if (lastError) {
21

  
22
        }
23

  
24
    }, [lastError])
25

  
18 26
    const [aspectRatio, setAspectRatio] = useState(1.0)
19 27

  
20 28
    const dispatch = useDispatch<AppDispatch>()
......
26 34

  
27 35
    }, [])
28 36

  
37

  
38

  
29 39
    return (
30 40
        <Center m={2} mb={10}>
31 41
            { loading ? (
src/pages/LoginPage.tsx
9 9
    Button,
10 10
    HStack,
11 11
    Text,
12
    KeyboardAvoidingView
12
    KeyboardAvoidingView,
13
    useToast
13 14
} from "native-base"
14
import { useCallback, useEffect, useState } from "react"
15
import { useCallback, useContext, useEffect, useState } from "react"
15 16
import { useDispatch, useSelector } from "react-redux"
16 17
import { checkAuth, login } from "../stores/actions/userThunks"
17 18
import { AppDispatch, RootState } from "../stores/store"
......
19 20
import { log } from "../logging/logger"
20 21
import * as SplashScreen from "expo-splash-screen"
21 22
import { ApplicationHeading } from "../components/reusables/ApplicationHeading"
23
import { InfoToast } from "../components/toast/InfoToast"
24
import { ErrorToast } from "../components/toast/ErrorToast"
25
import { SuccessToast } from "../components/toast/SuccessToast"
22 26

  
23 27

  
24 28
const LoginPage = () => {
25 29
    const [username, setUsername] = useState("")
26 30
    const [password, setPassword] = useState("")
31

  
27 32
    const lastError = useSelector((state: RootState) => state.user.lastError)
28 33

  
34
    const toast = useToast();
35

  
36

  
37
    useEffect(() => {
38
        if (lastError) {
39
            toast.closeAll()
40
            toast.show({
41
                render: ({
42
                    id
43
                }) => {
44
                    return <ErrorToast headerText={"Error"} text={lastError} onClose={() => toast.close(id)} />;
45
                },
46
                duration: 3000
47
            });
48
        }
49

  
50
    }, [lastError])
51

  
29 52
    const dispatch = useDispatch<AppDispatch>()
30 53

  
31 54
    const loginUser = () => {
32 55
        log.debug("LoginPage", "loginUser", "dispatching login")
33
        dispatch(login({username, password}))
34
        //TODO - add error handling
56
        dispatch(login({ username, password }))
35 57
    }
36 58

  
37

  
38 59
    useEffect(() => {
39 60
        dispatch(checkAuth())
40 61
    }, [])
41 62

  
42 63
    return (
43 64
        <KeyboardAvoidingView
44
            behavior={ Platform.OS === "ios" ? "padding" : "height" }
45
            flex={ 1 }
46
            justifyContent={ "center" }
47
            h={ {
65
            behavior={Platform.OS === "ios" ? "padding" : "height"}
66
            flex={1}
67
            justifyContent={"center"}
68
            h={{
48 69
                base: "400px",
49 70
                lg: "auto"
50
            } }
71
            }}
51 72
        >
52 73
            <Center w="100%">
53 74
                <VStack
54 75
                    p="2"
55 76
                    w="80%"
56
                    justifyContent={ "center" }
77
                    justifyContent={"center"}
57 78
                >
58 79
                    <ApplicationHeading />
59 80
                    <Heading
60 81
                        mt="10"
61 82
                        textAlign="center"
62
                        _dark={ {
83
                        _dark={{
63 84
                            color: "primary.500"
64
                        } }
85
                        }}
65 86

  
66 87
                        fontWeight="bold"
67 88
                        size="xl"
......
74 95
                    >
75 96
                        Please log in to continue
76 97
                    </Text>
77
                    { lastError && (
98
                    {lastError && (
78 99
                        <Text
79 100
                            mt="1"
80 101
                            textAlign="center"
81 102
                            color="error.500"
82 103
                        >
83
                            { lastError }
104
                            {lastError}
84 105
                        </Text>
85
                    ) }
106
                    )}
86 107

  
87
                    <VStack space={ 3 } >
108
                    <VStack space={3} >
88 109
                        <FormControl>
89 110
                            <FormControl.Label>Username</FormControl.Label>
90 111
                            <Input
91 112
                                // value={username}
92 113
                                textContentType={"username"}
93
                                rounded={ "xl" }
114
                                rounded={"xl"}
94 115
                                autoComplete={"username"}
95
                                onSubmitEditing={ () => { loginUser() } }
96
                                onChangeText={ (username) => setUsername(username) }
116
                                onSubmitEditing={() => { loginUser() }}
117
                                onChangeText={(username) => setUsername(username)}
97 118
                            />
98 119
                            <FormControl.Label>Password</FormControl.Label>
99 120
                            <Input
100 121
                                type="password"
101
                                autoComplete={ "password" }
102
                                id={ "password" }
103
                                returnKeyType={ "go" }
104
                                rounded={ "xl" }
105
                                onSubmitEditing={ () => loginUser() }
106
                                onChangeText={ (password) => setPassword(password) }
122
                                autoComplete={"password"}
123
                                id={"password"}
124
                                returnKeyType={"go"}
125
                                rounded={"xl"}
126
                                onSubmitEditing={() => loginUser()}
127
                                onChangeText={(password) => setPassword(password)}
107 128
                            />
108 129
                            <Button
109 130
                                mt="2"
110
                                bg={ "primary.500" }
111
                                onPress={ loginUser }
112
                                rounded={ "xl"}
131
                                bg={"primary.500"}
132
                                onPress={loginUser}
133
                                rounded={"xl"}
113 134
                            >
114 135
                                Sign in
115 136
                            </Button>

Také k dispozici: Unified diff