{currentLanguage === 'cz' ? (
-
} onClick={() => handleLanguageChange('en')}>
+
) : (
-
} onClick={() => handleLanguageChange('cz')}>
+
)}
diff --git a/src/constants.ts b/src/constants.ts
index 246d150..6c03b9e 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -1 +1,2 @@
export const daysOfWeek = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'];
+export const UserLogin: Readonly<{LOGIN: string}> = { LOGIN: 'login' };
\ No newline at end of file
diff --git a/src/i18n/locales/cz.json b/src/i18n/locales/cz.json
index 80f8ce2..26f214b 100644
--- a/src/i18n/locales/cz.json
+++ b/src/i18n/locales/cz.json
@@ -63,6 +63,16 @@
"somethingWrong": "Něco je špatně.",
"404": "Tato stránka neexistuje!"
},
+ "loginUser": {
+ "username": "Uživatelské jméno",
+ "password": "Heslo",
+ "registrationInfo": "Nemáš zatím účet?",
+ "registrationAction": "Zaregistrovat se můžeš zde"
+ },
+ "registration": {
+ "createAccount": "Vytvořit účet",
+ "submit":"Registrovat"
+ },
"notExist": "Tato kavárna pravděpodobně neexistuje!",
"profile": "Profil",
"account": "Můj účet",
diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json
index 298be21..baf8d4f 100644
--- a/src/i18n/locales/en.json
+++ b/src/i18n/locales/en.json
@@ -53,6 +53,16 @@
"somethingWrong": "Something is wrong.",
"404": "This page is doesn't exist!"
},
+ "loginUser": {
+ "username": "Username",
+ "password": "Password",
+ "registrationInfo": "Don't have an account?",
+ "registrationAction": "Sign up"
+ },
+ "registration": {
+ "createAccount": "Create your account",
+ "submit":"Sign up"
+ },
"notExist": "This cafe probably doesn't exist!",
"profile": "Profil",
"account": "My account",
diff --git a/src/components/Cafe/CafeDetail.tsx b/src/pages/CafeDetail.tsx
similarity index 92%
rename from src/components/Cafe/CafeDetail.tsx
rename to src/pages/CafeDetail.tsx
index 0266c8f..a1b75cc 100644
--- a/src/components/Cafe/CafeDetail.tsx
+++ b/src/pages/CafeDetail.tsx
@@ -7,14 +7,14 @@ import dayjs from 'dayjs';
import { Typography, Grid, Skeleton, Tooltip, IconButton } from '@mui/material';
import { LocalCafeOutlined, EditOutlined } from '@mui/icons-material';
-import { getCafeDetailData, updateCafeDetailData } from '../../Utils/apiUtils';
-import { setCafeDetail } from '../../store/cafeDetail';
-import { RootState } from '../../store';
+import { getCafeDetailData, updateCafeDetailData } from '../Utils/apiUtils';
+import { setCafeDetail } from '../store/cafeDetail';
+import { RootState } from '../store';
import 'tailwindcss/tailwind.css';
-import Map from '../../common/Map/AppMap';
-import { openTime, CafeDetailResponse } from '../../types/cafe';
-import EditCafeForm from './EditCafeForm';
+import Map from '../components/Map/AppMap';
+import { openTime, CafeDetailResponse } from '../types/cafe';
+import EditCafeForm from '../components/Cafe/EditCafeForm';
type ParamsType = {
id: string;
@@ -33,7 +33,7 @@ const CafeDetail: React.FC = () => {
const getCafeDetail = useCallback(async() => {
setIsLoading(true);
try {
- const detail = await getCafeDetailData(`/cafe/${id}`);
+ const detail = await getCafeDetailData(`/api/cafe/${id}`);
if (detail) {
dispatch(setCafeDetail(detail));
}
@@ -55,7 +55,7 @@ const CafeDetail: React.FC = () => {
const submitEditCafe = async(data: CafeDetailResponse) => {
setIsLoading(true);
try {
- await updateCafeDetailData(data, `/cafe/${id}`);
+ await updateCafeDetailData(data, `/api/cafe/${id}`);
} catch (err) {
console.error(err);
} finally {
diff --git a/src/components/Home/index.tsx b/src/pages/Home/index.tsx
similarity index 70%
rename from src/components/Home/index.tsx
rename to src/pages/Home/index.tsx
index f1acdaa..7922642 100644
--- a/src/components/Home/index.tsx
+++ b/src/pages/Home/index.tsx
@@ -1,9 +1,9 @@
import React, { useEffect } from 'react';
import { useDispatch } from 'react-redux';
-import Map from '../../common/Map/AppMap';
-import CafeList from '../Cafe/CafeList';
-import Navigation from '../Navigation/AppNavigation';
+import Map from '../../components/Map/AppMap';
+import CafeList from '../../components/Cafe/CafeList';
+import Navigation from '../../components/Navigation/AppNavigation';
import { getCafeList } from '../../Utils/apiUtils';
import { setCafes } from '../../store/cafeList';
@@ -18,7 +18,7 @@ const Home: React.FC
= () => {
useEffect(() => {
const setCafeList = async () => {
try {
- const response = await getCafeList('/cafe/list');
+ const response = await getCafeList('/api/cafe/list');
if (response) {
dispatch(setCafes(response));
}
@@ -32,11 +32,11 @@ const Home: React.FC = () => {
return (
- <>
+
- >
+
)
}
diff --git a/src/pages/Login/Login.tsx b/src/pages/Login/Login.tsx
new file mode 100644
index 0000000..0ee925c
--- /dev/null
+++ b/src/pages/Login/Login.tsx
@@ -0,0 +1,98 @@
+import { FC } from 'react';
+import { useForm } from 'react-hook-form';
+import { useTranslation } from 'react-i18next';
+import { useHistory } from 'react-router-dom';
+import { useDispatch } from 'react-redux';
+
+import FormTextField from '../../components/common/FormComponets/FormTextField';
+import { Button, Card, CardActions, CardContent, Grid, Link, Typography } from '@mui/material';
+import { httpPost } from '../../Utils/axiosService';
+import { UserLogin } from '../../constants';
+import { setLogin } from '../../store/settings';
+import { FieldErrors } from '../../types/cafe';
+
+type FormValues = {
+ username: string;
+ password: string;
+};
+
+const Login: FC = () => {
+ const { t } = useTranslation();
+ const { control, formState: { errors }, handleSubmit, reset } = useForm();
+ const history = useHistory();
+ const dispatch = useDispatch();
+
+ const fieldErrors = {
+ username: errors.username,
+ password: errors.password,
+ }
+
+ const onSubmit = (values: FormValues) => {
+ createNewUser(values);
+ reset();
+ }
+
+ const createNewUser = async (data: FormValues) => {
+ try {
+ await httpPost('/api/user/login', data);
+ localStorage.setItem(UserLogin.LOGIN, 'true')
+ dispatch(setLogin(true));
+ history.push('/');
+ } catch (error) {
+ console.error(error.response.data.message);
+ fieldErrors.username = error.response.data.message;
+ console.log(fieldErrors)
+ }
+ };
+
+ return (
+ <>
+
+
+
+ >
+ );
+};
+
+export default Login;
diff --git a/src/pages/Registration/Registration.tsx b/src/pages/Registration/Registration.tsx
new file mode 100644
index 0000000..f0a4b63
--- /dev/null
+++ b/src/pages/Registration/Registration.tsx
@@ -0,0 +1,75 @@
+import { FC, useEffect, useState } from 'react';
+import { useForm } from 'react-hook-form';
+import { useTranslation } from 'react-i18next';
+
+import FormTextField from '../../components/common/FormComponets/FormTextField';
+import { Button, Card, CardActions, CardContent, Grid, Typography } from '@mui/material';
+import { httpPost } from '../../Utils/axiosService';
+
+type FormValues = {
+ username: string;
+ password: string;
+};
+
+const Registration: FC = () => {
+ const { t } = useTranslation();
+ const { control, formState: { errors }, handleSubmit, reset } = useForm();
+
+ const fieldErrors = {
+ username: errors.username,
+ password: errors.password,
+ }
+
+ const onSubmit = (values: FormValues) => {
+ console.log(values);
+ createNewUser(values);
+ reset();
+ }
+
+ const createNewUser = async (data: FormValues) => {
+ try {
+ await httpPost('/api/user/registration', data);
+ } catch (error) {
+ console.error(error);
+ }
+ };
+
+ return (
+ <>
+
+
+
+ >
+ );
+};
+
+export default Registration;
diff --git a/src/routes/index.jsx b/src/routes/index.jsx
index 125bea0..3a4b38d 100644
--- a/src/routes/index.jsx
+++ b/src/routes/index.jsx
@@ -1,6 +1,7 @@
-import CafeDetail from '../components/Cafe/CafeDetail';
-import Home from '../components/Home';
-import AppRegistration from '../components/Registration/AppRegistration';
+import CafeDetail from '../pages/CafeDetail';
+import Home from '../pages/Home';
+import Registration from '../pages/Registration/Registration';
+import Login from '../pages/Login/Login';
/**
* Sorts routes
@@ -28,13 +29,6 @@ const sortRoutes = (routes, sortBy, sortOrder) => {
* @prop {string} label - label pro routu - da se pouzit jako title h1 atp.
* @prop {order} number - pozice napriklad pro menu, pokud chces treba pouzit pro linky v nejake navigaci- Sortuji se dole v exportu
* @prop {JSXElement | Element} route - Element nebo Komponent ktery se ma renderovat
- * @prop {boolean?} inFooter - pouziva se pro filter exportu routes pro footer, napr. navigace ve footeru - nepovinne
- * @prop {boolean?} inHeader - pouziva se pro filter exportu routes pro header, napr. navigace v headeru - nepovinne
- * @prop {JSXElement | Element | SVGElement | null} icon - muze se pouzit jako ikona pro navigaci napriklad - nepovinne
- * @prop {boolean?} disabled - zamezí exportu routy a ta bude nedosupná - nepovinne
- * @prop {string?} additionalClass - doplňkové classy pro danou routu jako jeden string napr.: 'class-1 class-2 ...' - nepovinne
- */
-
/**
* Routes
* pole Route
@@ -49,25 +43,31 @@ const routes = [
order: 1,
route: ,
},
+ {
+ exact: false,
+ path: '/cafe/:id',
+ label: 'Detail',
+ order: 4,
+ route:
+ },
{
exact: false,
path: '/registration',
label: 'Registrace',
- order: 3,
- route:
+ order: 5,
+ route:
},
{
exact: false,
- path: '/cafe/:id',
- label: 'Detail',
- order: 4,
- route:
+ path: '/login',
+ label: 'Login',
+ order: 5,
+ route:
},
];
-// zde se meguji a sortuji vsechn pole s routami
export const AllRoutes = sortRoutes(routes.filter(route => !route.disabled));
-// toto je treba pro navigaci v headeru
+
export const HeaderNavItems = AllRoutes.filter(route => route.inHeader);
-// toto je treba pro navigaci ve footeru
+
export const FooterNavItems = AllRoutes.filter(route => route.inFooter);
diff --git a/src/store/settings.ts b/src/store/settings.ts
index 2cd0744..0af7844 100644
--- a/src/store/settings.ts
+++ b/src/store/settings.ts
@@ -2,10 +2,12 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit';
interface SettingsState {
language: string;
+ isLogin: boolean;
}
const initialState: SettingsState = {
- language: 'en'
+ language: 'en',
+ isLogin: false,
};
export const settingsSlice = createSlice({
@@ -14,9 +16,15 @@ export const settingsSlice = createSlice({
reducers: {
setLanguage: (state, action: PayloadAction) => {
state.language = action.payload;
+ },
+ setLogin: (state, action: PayloadAction) => {
+ state.isLogin = action.payload;
+ },
+ checkLoginUser: (state, action: PayloadAction) => {
+ state.isLogin = action.payload;
}
}
});
-export const { setLanguage } = settingsSlice.actions;
+export const { setLanguage, setLogin, checkLoginUser } = settingsSlice.actions;
export default settingsSlice.reducer;