commit c8be2597d03290464754de224d7520b2fdc7fd0f
Author: Fantič <58391275+FantaFantic@users.noreply.github.com>
Date:   Tue Oct 17 15:41:38 2023 +0200

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

diff --git a/src/components/toast/ErrorToast.tsx b/src/components/toast/ErrorToast.tsx
new file mode 100644
index 0000000..aef8b45
--- /dev/null
+++ b/src/components/toast/ErrorToast.tsx
@@ -0,0 +1,51 @@
+
+import React from 'react';
+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";
+
+
+interface ErrorToastProps {
+    headerText?: string
+    text: string
+    onClose: () => void
+}
+
+export const ErrorToast = (props: ErrorToastProps) => {
+
+    const { text, headerText, onClose } = props;
+
+    return (
+        <Alert
+            alignSelf="center"
+            flexDirection="row"
+            variant="outline"
+            status="warning"
+            backgroundColor={"error.50"}
+        >
+            <VStack>
+                <HStack space={2} flexShrink={1} alignItems="center">
+                    <Alert.Icon size="xs" />
+                    {headerText ?
+                        <Text fontSize="sm" fontWeight="medium" color="error.700">
+                            {headerText}
+                        </Text> :
+                        <Text fontSize="xs" color="error.500">
+                            {text}
+                        </Text>}
+                    <Spacer />
+                    <IconButton
+                        variant="unstyled"
+                        icon={<CloseIcon size="3" color="error.500" />}
+                        onPress={() => {
+                            onClose();
+                        }}
+                    />
+                </HStack>
+                {headerText &&
+                    <Text fontSize="xs" color="error.500">
+                        {text}
+                    </Text>}
+            </VStack>
+        </Alert>
+    )
+}
+
diff --git a/src/components/toast/InfoToast.tsx b/src/components/toast/InfoToast.tsx
new file mode 100644
index 0000000..007b097
--- /dev/null
+++ b/src/components/toast/InfoToast.tsx
@@ -0,0 +1,50 @@
+
+import React from 'react';
+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";
+
+interface InfoToastProps {
+    headerText?: string
+    text: string
+    onClose: () => void
+}
+
+export const InfoToast = (props: InfoToastProps) => {
+
+    const { text, headerText, onClose } = props;
+
+    return (
+        <Alert
+            alignSelf="center"
+            flexDirection="row"
+            variant="outline"
+            status="info"
+            backgroundColor={"info.50"}
+        >
+            <VStack>
+                <HStack space={2} flexShrink={1} alignItems="center">
+                    <Alert.Icon size="xs" />
+                    {headerText ?
+                        <Text fontSize="sm" fontWeight="medium" color="info.700">
+                            {headerText}
+                        </Text> :
+                        <Text fontSize="xs" color="info.500">
+                            {text}
+                        </Text>}
+                    <Spacer />
+                    <IconButton
+                        variant="unstyled"
+                        icon={<CloseIcon size="3" color="info.500" />}
+                        onPress={() => {
+                            onClose();
+                        }}
+                    />
+                </HStack>
+                {headerText &&
+                    <Text fontSize="xs" color="info.500">
+                        {text}
+                    </Text>}
+            </VStack>
+        </Alert>
+    )
+};
+
diff --git a/src/components/toast/SuccessToast.tsx b/src/components/toast/SuccessToast.tsx
new file mode 100644
index 0000000..e3c54e3
--- /dev/null
+++ b/src/components/toast/SuccessToast.tsx
@@ -0,0 +1,51 @@
+
+import React from 'react';
+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";
+
+
+interface SuccessToastProps {
+    headerText?: string
+    text: string
+    onClose: () => void
+}
+
+export const SuccessToast = (props: SuccessToastProps) => {
+
+    const { text, headerText, onClose } = props;
+
+    return (
+        <Alert
+            alignSelf="center"
+            flexDirection="row"
+            variant="outline"
+            status="success"
+            backgroundColor={"success.50"}
+        >
+            <VStack>
+                <HStack space={2} flexShrink={1} alignItems="center">
+                    <Alert.Icon size="xs" />
+                    {headerText ?
+                        <Text fontSize="sm" fontWeight="medium" color="success.700">
+                            {headerText}
+                        </Text> :
+                        <Text fontSize="xs" color="success.500">
+                            {text}
+                        </Text>}
+                    <Spacer />
+                    <IconButton
+                        variant="unstyled"
+                        icon={<CloseIcon size="3" color="success.500" />}
+                        onPress={() => {
+                            onClose();
+                        }}
+                    />
+                </HStack>
+                {headerText &&
+                    <Text fontSize="xs" color="success.500">
+                        {text}
+                    </Text>}
+            </VStack>
+        </Alert>
+    )
+};
+
diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx
index 35e706f..e86f5b6 100644
--- a/src/pages/HomePage.tsx
+++ b/src/pages/HomePage.tsx
@@ -1,7 +1,7 @@
 import { Center, Image, Pressable, ScrollView, Text } from "native-base"
 import { useDispatch, useSelector } from "react-redux"
 import { AppDispatch, RootState } from "../stores/store"
-import { useEffect, useState } from "react"
+import { useContext, useEffect, useState } from "react"
 import { fetchData } from "../stores/actions/homePageThunks"
 import { ApplicationHeading } from "../components/reusables/ApplicationHeading"
 import LoadingBox from "../components/loading/LoadingBox"
@@ -14,7 +14,15 @@ import { HOME_PAGE_IMG_URL } from "../api/constants"
 const HomePage = ({navigation}: DrawerScreenProps<RootDrawerParamList, 'Home'>) => {
     const data = useSelector((state: RootState) => state.homePage.data)
     const loading = useSelector((state: RootState) => state.homePage.loading)
-    const error = useSelector((state: RootState) => state.homePage.lastError)
+    const lastError = useSelector((state: RootState) => state.homePage.lastError)
+
+    useEffect(() => {
+        if (lastError) {
+
+        }
+
+    }, [lastError])
+
     const [aspectRatio, setAspectRatio] = useState(1.0)
 
     const dispatch = useDispatch<AppDispatch>()
@@ -26,6 +34,8 @@ const HomePage = ({navigation}: DrawerScreenProps<RootDrawerParamList, 'Home'>)
 
     }, [])
 
+
+
     return (
         <Center m={2} mb={10}>
             { loading ? (
diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx
index b6a5289..76dcacd 100644
--- a/src/pages/LoginPage.tsx
+++ b/src/pages/LoginPage.tsx
@@ -9,9 +9,10 @@ import {
     Button,
     HStack,
     Text,
-    KeyboardAvoidingView
+    KeyboardAvoidingView,
+    useToast
 } from "native-base"
-import { useCallback, useEffect, useState } from "react"
+import { useCallback, useContext, useEffect, useState } from "react"
 import { useDispatch, useSelector } from "react-redux"
 import { checkAuth, login } from "../stores/actions/userThunks"
 import { AppDispatch, RootState } from "../stores/store"
@@ -19,49 +20,69 @@ import { Platform } from "react-native"
 import { log } from "../logging/logger"
 import * as SplashScreen from "expo-splash-screen"
 import { ApplicationHeading } from "../components/reusables/ApplicationHeading"
+import { InfoToast } from "../components/toast/InfoToast"
+import { ErrorToast } from "../components/toast/ErrorToast"
+import { SuccessToast } from "../components/toast/SuccessToast"
 
 
 const LoginPage = () => {
     const [username, setUsername] = useState("")
     const [password, setPassword] = useState("")
+
     const lastError = useSelector((state: RootState) => state.user.lastError)
 
+    const toast = useToast();
+
+
+    useEffect(() => {
+        if (lastError) {
+            toast.closeAll()
+            toast.show({
+                render: ({
+                    id
+                }) => {
+                    return <ErrorToast headerText={"Error"} text={lastError} onClose={() => toast.close(id)} />;
+                },
+                duration: 3000
+            });
+        }
+
+    }, [lastError])
+
     const dispatch = useDispatch<AppDispatch>()
 
     const loginUser = () => {
         log.debug("LoginPage", "loginUser", "dispatching login")
-        dispatch(login({username, password}))
-        //TODO - add error handling
+        dispatch(login({ username, password }))
     }
 
-
     useEffect(() => {
         dispatch(checkAuth())
     }, [])
 
     return (
         <KeyboardAvoidingView
-            behavior={ Platform.OS === "ios" ? "padding" : "height" }
-            flex={ 1 }
-            justifyContent={ "center" }
-            h={ {
+            behavior={Platform.OS === "ios" ? "padding" : "height"}
+            flex={1}
+            justifyContent={"center"}
+            h={{
                 base: "400px",
                 lg: "auto"
-            } }
+            }}
         >
             <Center w="100%">
                 <VStack
                     p="2"
                     w="80%"
-                    justifyContent={ "center" }
+                    justifyContent={"center"}
                 >
                     <ApplicationHeading />
                     <Heading
                         mt="10"
                         textAlign="center"
-                        _dark={ {
+                        _dark={{
                             color: "primary.500"
-                        } }
+                        }}
 
                         fontWeight="bold"
                         size="xl"
@@ -74,42 +95,42 @@ const LoginPage = () => {
                     >
                         Please log in to continue
                     </Text>
-                    { lastError && (
+                    {lastError && (
                         <Text
                             mt="1"
                             textAlign="center"
                             color="error.500"
                         >
-                            { lastError }
+                            {lastError}
                         </Text>
-                    ) }
+                    )}
 
-                    <VStack space={ 3 } >
+                    <VStack space={3} >
                         <FormControl>
                             <FormControl.Label>Username</FormControl.Label>
                             <Input
                                 // value={username}
                                 textContentType={"username"}
-                                rounded={ "xl" }
+                                rounded={"xl"}
                                 autoComplete={"username"}
-                                onSubmitEditing={ () => { loginUser() } }
-                                onChangeText={ (username) => setUsername(username) }
+                                onSubmitEditing={() => { loginUser() }}
+                                onChangeText={(username) => setUsername(username)}
                             />
                             <FormControl.Label>Password</FormControl.Label>
                             <Input
                                 type="password"
-                                autoComplete={ "password" }
-                                id={ "password" }
-                                returnKeyType={ "go" }
-                                rounded={ "xl" }
-                                onSubmitEditing={ () => loginUser() }
-                                onChangeText={ (password) => setPassword(password) }
+                                autoComplete={"password"}
+                                id={"password"}
+                                returnKeyType={"go"}
+                                rounded={"xl"}
+                                onSubmitEditing={() => loginUser()}
+                                onChangeText={(password) => setPassword(password)}
                             />
                             <Button
                                 mt="2"
-                                bg={ "primary.500" }
-                                onPress={ loginUser }
-                                rounded={ "xl"}
+                                bg={"primary.500"}
+                                onPress={loginUser}
+                                rounded={"xl"}
                             >
                                 Sign in
                             </Button>
