commit 5ed9692c6b049e3ea812c507c32c4cb7fbdf4c80
Author: Schwobik <michal.schwob@seznam.cz>
Date:   Tue Apr 4 23:57:23 2023 +0200

    #re 10171
    Demo of application login with redux, axios and nativeBase. Tested

diff --git a/App.tsx b/App.tsx
index ca35e22..08d13e8 100644
--- a/App.tsx
+++ b/App.tsx
@@ -2,13 +2,16 @@ import { StatusBar } from 'expo-status-bar'
 import { StyleSheet, Text, View } from 'react-native'
 import { NativeBaseProvider, Box } from "native-base"
 import LoginPage from './src/pages/LoginPage'
-import ScrollViewTest from "./src/pages/ScrollViewTest"
+import { Provider } from "react-redux"
+import store from "./src/stores/store"
 
 export default function App() {
   return (
-      <NativeBaseProvider>
-        <ScrollViewTest />
-      </NativeBaseProvider>
+      <Provider store={store}>
+          <NativeBaseProvider>
+            <LoginPage />
+          </NativeBaseProvider>
+      </Provider>
   )
 }
 
diff --git a/package.json b/package.json
index 5d30731..8710e2a 100644
--- a/package.json
+++ b/package.json
@@ -15,10 +15,12 @@
     "expo-status-bar": "~1.4.4",
     "native-base": "^3.4.28",
     "react": "18.2.0",
+    "react-dom": "^18.2.0",
     "react-native": "0.71.4",
     "react-native-deck-swiper": "^2.0.13",
     "react-native-safe-area-context": "4.5.0",
     "react-native-svg": "13.4.0",
+    "react-redux": "^8.0.5",
     "redux": "^4.2.1",
     "typescript": "^4.9.4"
   },
diff --git a/src/api/api.ts b/src/api/api.ts
index f8105c7..6696295 100644
--- a/src/api/api.ts
+++ b/src/api/api.ts
@@ -1,6 +1,7 @@
 import axios from "axios"
 import { BASE_URL } from "./constants"
 
+
 export const axiosInstance = axios.create({
     baseURL: BASE_URL,
     withCredentials: true
diff --git a/src/api/authservice.ts b/src/api/authservice.ts
index 81057f7..91b4c11 100644
--- a/src/api/authservice.ts
+++ b/src/api/authservice.ts
@@ -1,13 +1,11 @@
 import { axiosInstance } from "./api"
 
-export const login = (username: string, password: string) => {
-    axiosInstance.post(
+export const loginRequest = async (username: string, password: string) => {
+    return await axiosInstance.post(
         "/api/login",
         {
             username: username,
             password: password
         }
-    ).then((response) => {
-        console.log(response)
-    })
+    )
 }
\ No newline at end of file
diff --git a/src/components/.gitkeep b/src/components/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx
index 0fa8360..cc78c14 100644
--- a/src/pages/LoginPage.tsx
+++ b/src/pages/LoginPage.tsx
@@ -1,29 +1,23 @@
 import { Center, Box, Heading, VStack, FormControl, Link, Input, Button, HStack, Text } from "native-base"
-import { axiosInstance } from "../api/api"
+import { useState } from "react"
+import { useDispatch, useSelector } from "react-redux"
+import { login } from "../stores/actions/userThunks"
+import { AppDispatch, RootState } from "../stores/store"
 
-let text: number = 199
-const fakeLogin = async () => {
-    text = 101
-    axiosInstance.post(
-        '/api/login/',
-        {"username": "viktorie", "password": "Golem123."}
-    ).then((response) => {
-        text = response.status
-        console.log(response)
-    })
-}
 
-const fakeRequest = async () => {
-    text = 101
-    console.log("request")
-    axiosInstance.get(
-        '/api/users'
-    ).then((response) => {
-        text = response.status
-        console.log(response)
-    })
-}
 const LoginPage = () => {
+    const [username, setUsername] = useState("")
+    const [password, setPassword] = useState("")
+    const status = useSelector((state: RootState) => state.user.loggedIn)
+
+    const dispatch = useDispatch<AppDispatch>()
+
+    const loginUser = () => {
+        dispatch(login({ username, password }))
+        //TODO - add error handling
+        //TODO add redirect to home page
+    }
+
     return (
         <Center w="100%">
             <Box safeArea p="2" py="8" w="90%" maxW="290">
@@ -40,12 +34,18 @@ const LoginPage = () => {
 
                 <VStack space={3} mt="5">
                     <FormControl>
-                        <FormControl.Label>Email ID</FormControl.Label>
-                        <Input />
+                        <FormControl.Label>Username</FormControl.Label>
+                        <Input
+                            // value={username}
+                            onChangeText={(username) => setUsername(username)}
+                        />
                     </FormControl>
                     <FormControl>
                         <FormControl.Label>Password</FormControl.Label>
-                        <Input type="password" />
+                        <Input type="password"
+                            // value={password}
+                            onChangeText={(password) => setPassword(password)}
+                        />
                         <Link _text={{
                             fontSize: "xs",
                             fontWeight: "500",
@@ -54,7 +54,11 @@ const LoginPage = () => {
                             Forget Password?
                         </Link>
                     </FormControl>
-                    <Button mt="2" colorScheme="indigo">
+                    <Button
+                        mt="2"
+                        colorScheme="indigo"
+                        onPress={() => loginUser()}
+                    >
                         Sign in
                     </Button>
                     <HStack mt="6" justifyContent="center">
diff --git a/src/pages/ScrollViewTest.tsx b/src/pages/ScrollViewTest.tsx
deleted file mode 100644
index fcc8581..0000000
--- a/src/pages/ScrollViewTest.tsx
+++ /dev/null
@@ -1,89 +0,0 @@
-import {
-    Center,
-    Box,
-    Heading,
-    VStack,
-    FormControl,
-    Link,
-    Input,
-    Button,
-    HStack,
-    Text,
-    ScrollView,
-    Image
-} from "native-base"
-import { axiosInstance } from "../api/api"
-
-
-
-const ScrollViewTest = () => {
-    const images = ["VieB-7.jpg", "VieB-10.jpg", "VieB-11.jpg", "VieB-14.jpg", "VieB-15.jpg"]
-
-    return (
-        <ScrollView>
-            <Center w="100%">
-                <Box safeArea p="2" py="8" w="90%" maxW="290">
-                    <Heading size="lg" fontWeight="600" color="coolGray.800" _dark={{
-                        color: "warmGray.50"
-                    }}>
-                        Welcome
-                    </Heading>
-                    <Heading mt="1" _dark={{
-                        color: "warmGray.200"
-                    }} color="coolGray.600" fontWeight="medium" size="xs">
-                        Sign in to continue!
-                    </Heading>
-
-                    <VStack space={3} mt="5">
-                        <FormControl>
-                            <FormControl.Label>Email ID</FormControl.Label>
-                            <Input />
-                        </FormControl>
-                        <FormControl>
-                            <FormControl.Label>Password</FormControl.Label>
-                            <Input type="password" />
-                            <Link _text={{
-                                fontSize: "xs",
-                                fontWeight: "500",
-                                color: "indigo.500"
-                            }} alignSelf="flex-end" mt="1">
-                                Forget Password?
-                            </Link>
-                        </FormControl>
-                        <Button mt="2" colorScheme="indigo">
-                            Sign in
-                        </Button>
-                        <HStack mt="6" justifyContent="center">
-                            <Text fontSize="sm" color="coolGray.600" _dark={{
-                                color: "warmGray.200"
-                            }}>
-                                I'm a new user.{" "}
-                            </Text>
-                            <Link _text={{
-                                color: "indigo.500",
-                                fontWeight: "medium",
-                                fontSize: "sm"
-                            }} href="#">
-                                Sign Up
-                            </Link>
-                        </HStack>
-                    </VStack>
-                </Box>
-                <ScrollView horizontal={true}>
-                    {images.map((name, index) => (
-                        <Image
-                            source={{uri: "http://147.228.173.159/static/images/"+name}}
-                            w={150}
-                            h={150}
-                            marginX={2}
-                            alt={name}
-                        />
-                    ))}
-                </ScrollView>
-
-            </Center>
-        </ScrollView>
-    )
-}
-
-export default ScrollViewTest
\ No newline at end of file
diff --git a/src/stores/actions/userThunks.ts b/src/stores/actions/userThunks.ts
index 8796a85..65201f8 100644
--- a/src/stores/actions/userThunks.ts
+++ b/src/stores/actions/userThunks.ts
@@ -1,23 +1,23 @@
 import { createAsyncThunk } from "@reduxjs/toolkit"
 import { axiosInstance } from "../../api/api"
+import { loginRequest } from "../../api/authservice"
 
 export const login = createAsyncThunk(
     "user/login",
-    async (payload: { username: string, password: string }, thunkAPI) => {
-        const response = await axiosInstance.post(
-            "/api/login",
-            {
-                username: payload.username,
-                password: payload.password,
+    async (payload: { username: string, password: string }) => {
+        try {
+            const response = await loginRequest(payload.username, payload.password)
+            console.log(response)
+            if (response.status === 200) {
+                return {
+                    username: payload.username,
+                    role: response.data.role
+                }
+            } else {
+                return Promise.reject(response.data ? response.data : "Login failed")
             }
-        )
-        if (response.status === 200) {
-            return {
-                username: payload.username,
-                role: response.data.role
-            }
-        } else {
-            return Promise.reject(response.data ? response.data : "Login failed")
+        } catch (err: any) {
+            return Promise.reject(err.response.data)
         }
     }
 )
\ No newline at end of file
diff --git a/src/stores/store.ts b/src/stores/store.ts
index 8bae62f..a5e5032 100644
--- a/src/stores/store.ts
+++ b/src/stores/store.ts
@@ -1,8 +1,13 @@
 import { configureStore } from "@reduxjs/toolkit"
 import userReducer from "./reducers/userSlice"
 
-export default configureStore({
+const store = configureStore({
     reducer: {
         user: userReducer,
     },
-})
\ No newline at end of file
+})
+
+export default store
+export type RootState = ReturnType<typeof store.getState>
+export type AppStore = typeof store
+export type AppDispatch = typeof store.dispatch
