Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
gramovi4a committed May 27, 2024
2 parents 99ab6f8 + 219b38f commit c05d411
Show file tree
Hide file tree
Showing 44 changed files with 1,173 additions and 702 deletions.
3 changes: 2 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from "react";
import React, {useEffect} from "react";

import {AppProvider} from "./providers/app";

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import storage from "./utils/storage";



Expand Down
29 changes: 25 additions & 4 deletions src/components/Layout/MainLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {NavLink, Link} from 'react-router-dom';
import logo from '../../assets/Logo.svg';
import {useLogout, useUser} from "../../lib/auth";
import Heading from "../Elements/Headings/Heading";
import storage from '../../utils/storage';



type SideNavigationItem = {
Expand All @@ -36,6 +38,8 @@ const SideNavigation = () => {
const handleClick = (index:any) => {
setActive(index);
};



return (
<>
Expand Down Expand Up @@ -82,6 +86,8 @@ const UserNavigation = () => {
const user = useUser();
const userName = user.data?.email;




return (
<Menu as="div" className="ml-3 relative">
Expand Down Expand Up @@ -141,6 +147,9 @@ type MobileSidebarProps = {
sidebarOpen: boolean;
setSidebarOpen: React.Dispatch<React.SetStateAction<boolean>>;
};
//Get the clock from the storage :

const clockData : {name : string, clockId : string} = storage.getClock() ? storage.getClock() : {name : "No clock selected", clockId : "SELECTACLOCK"}

const MobileSidebar = ({sidebarOpen, setSidebarOpen}: MobileSidebarProps) => {
return (
Expand Down Expand Up @@ -199,10 +208,16 @@ const MobileSidebar = ({sidebarOpen, setSidebarOpen}: MobileSidebarProps) => {
</nav>
</div>
<div className="flex flex-col h-16 flex-shrink-0 px-4 bg-white">
<NavLink
key={"clock"}
to={'./settings'}
className="block"
>
<div className={"bg-primaryColorOpacity p-2 rounded"}>
<Heading text={"Clock: Kabelikova"} className={"text-center"} type={"heading3"}/>
<Heading text={"Id:123"} className={"text-center"} type={"heading5"}/>
<Heading text={clockData.name} className={"text-center"} type={"heading3"}/>
<Heading text={clockData.clockId} className={"text-center"} type={"heading5"}/>
</div>
</NavLink>
</div>
</div>
</Transition.Child>
Expand All @@ -226,10 +241,16 @@ const Sidebar = () => {
</nav>
</div>
<div className="flex flex-col h-20 flex-shrink-0 px-6 bg-gray-900">
<NavLink
key={"clock"}
to={'./settings'}
className="block"
>
<div className={"bg-primaryColorOpacity p-2 rounded"}>
<Heading text={"Clock: Kabelikova"} className={"text-center"} type={"heading3"}/>
<Heading text={"Id:123"} className={"text-center"} type={"heading5"}/>
<Heading text={clockData.name} className={"text-center"} type={"heading3"}/>
<Heading text={clockData.clockId} className={"text-center"} type={"heading5"}/>
</div>
</NavLink>

</div>
</div>
Expand Down
9 changes: 1 addition & 8 deletions src/features/alarm/api/alarmApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,4 @@ export const deleteAlarm = ( alarmId: string): Promise<void> => {
throw error.response.data;
});
};
/*
export const getDummyAlarms = (): Promise<AlarmPropsResponse[]> => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(dummyAlarms);
}, 1000); // Simulate a 1 second delay for the mock API call
});
};*/

40 changes: 30 additions & 10 deletions src/features/alarm/components/AddAlarm.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState } from "react";
import {useEffect, useState} from "react";
import Heading from "../../../components/Elements/Headings/Heading";
import InputField from "../../../components/Form/InputField";
import { LocalizationProvider, TimePicker } from "@mui/x-date-pickers";
Expand All @@ -9,16 +9,17 @@ import Button from "../../../components/Elements/Button";
import {CreateAlarmProps} from "../types";
import { createAlarm} from "../api/alarmApi";
import SelectForm from "../../../components/Form/selectForm";
import {SimpleClockProps} from "../../clockSettings/types";
import {ClockPropsResponse, SimpleClockProps} from "../../clockSettings/types";
import {getAllClocks} from "../../clockSettings/api/clockApi";
import storage from "../../../utils/storage";


interface AddAlarmProps {
change: boolean;
setChange: React.Dispatch<React.SetStateAction<boolean>>;
}


const AddAlarm: React.FC<AddAlarmProps> = ({change, setChange}) => {
const AddAlarm: React.FC<AddAlarmProps> = ({ setChange}) => {
const [alarmName, setAlarmName] = useState("");
const [nameError, setNameError] = useState("");
const [alarmTime, setAlarmTime] = React.useState<Dayjs | null>(null);
Expand All @@ -28,11 +29,31 @@ const AddAlarm: React.FC<AddAlarmProps> = ({change, setChange}) => {
id: 0,
name: "Select",
});
const [clocks, setClocks] = useState<SimpleClockProps[]>([]);
useEffect(() => {
const fetchClocks = async () => {
try {
console.log("inside try of fetching clocks");
const response = await getAllClocks(storage.getUser().userId); // Adjust the endpoint to your API
const clocks: SimpleClockProps[] = response.map(clock => ({
id: clock.id,
name: clock.name
}));
setClocks(clocks);
console.log("clocks"+clocks);
} catch (error) {
console.error('Error fetching clocks:', error);
}
};

fetchClocks();
}, []);

const clocks: SimpleClockProps[] = [
{ id: "f656d97d-63b7-451a-91ee-0e620e652c9e", name: "Alexa" },
{ id: "f656d97d-63b7-451a-91ee-0e620e652c99", name: "Ricardo clock" }
];
const toggleChangeAfterTwoSeconds = () => {
setTimeout(() => {
setChange(prevChange => !prevChange);
}, 500); // 2000 milliseconds = 2 seconds
};

const handleAddAlarm = () => {
if (!alarmTime) {
Expand All @@ -54,11 +75,10 @@ const AddAlarm: React.FC<AddAlarmProps> = ({change, setChange}) => {
minutes: Number(alarmTime.format("mm")),
name: alarmName,
}
setChange(!change);
console.log(createAlarmData);
createAlarm(createAlarmData).then((response) => {
console.log(response);
setChange(!change)
toggleChangeAfterTwoSeconds()
}).catch(
(error) => {
console.log(error);
Expand Down
15 changes: 0 additions & 15 deletions src/features/alarm/components/AlarmsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,6 @@ const AlarmsList: React.FC<AlarmsListProps> = (change) => {
const [loading, setLoading] = useState<boolean>(false);
const [error, setError] = useState<string | null>(null);

/*
const toggleEnabled = (name: string, time: string) => {
const updatedAlarms = alarms.map(alarm => {
if (alarm.name === name && alarm.setOffTime === time) {
return { ...alarm, isEnabled: !alarm.isActive };
}
return alarm;
});
setAlarms(updatedAlarms);
};
*/

const setAllAlarms = (response: AlarmsPropsResponse) => {
setAlarms(response.alarms);
Expand All @@ -44,11 +33,7 @@ const AlarmsList: React.FC<AlarmsListProps> = (change) => {
const response = await getAllAlarmsByClockId(clockId);
//const response = await getDummyAlarms();
await setAllAlarms(response);
console.log('Response', response);
console.log('alarmsVar', response);
console.log('changestat', change);
} catch (error) {
console.error('Failed to fetch alarms:', error);
setError('Failed to fetch alarms. Please try again later.');
} finally {
setLoading(false);
Expand Down
20 changes: 1 addition & 19 deletions src/features/auth/api/getUser.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1 @@

import { AuthUser } from '../types';

import hardCodedUser from "./hardcodedUser.json";
// getting user data from the backend by sending JWT token
//todo: getting user data from the backend by sending JWT token, example https://github.com/alan2207/react-query-auth/blob/master/examples/vite/src/lib/api.ts#L8
export const getUser = (): Promise<{ user: AuthUser | undefined}> => {

const hardcodedUser = hardCodedUser as AuthUser;
if(!Object.keys(hardcodedUser).length) {
return Promise.reject(new Error('No user data available'));
}
else {
return Promise.resolve({user: hardcodedUser});
}
//return axios.get('/auth/me');
//return Promise.reject(new Error('No user data available'))
//return Promise.resolve({user: hardcodedUserData});
};
export {}
32 changes: 12 additions & 20 deletions src/features/auth/api/login.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,18 @@
import { UserResponse } from '../types';
import {CreateUserPropsRequest, CreateUserPropsResponse, LoginPropsRequest, UserPropsResponse} from '../types';
import axios from "axios";
import {axiosConfigAuth, baseURL} from "../../../lib/axios";


//what I send
export type LoginCredentialsDTO = {
email: string;
password: string;
};

export const loginWithEmailAndPassword = (
data: LoginCredentialsDTO
): Promise<UserResponse> => {
//this will be received from backend and stored locally in the client
const hardcodedUserData: UserResponse = {
jwt: 'mock_jwt_token', // Hardcoded JWT token
user: {
id: '1',
email: data.email,
name: 'John Doe'
}
};
// Return a Promise that immediately resolves with the hardcoded user data
return Promise.resolve(hardcodedUserData);
export const loginWithEmailAndPassword = (data: LoginPropsRequest): Promise<UserPropsResponse> => {
return axios.post(`${baseURL}/UserService/users/login`, data, axiosConfigAuth)
.then(response => response.data)
.catch(error => {
console.log("error "+error.response.data)
throw error.response.data;
});
};

/*export const loginWithEmailAndPassword = (data: LoginCredentialsDTO): Promise<UserResponse> => {
return axios.post('/auth/login', data);
};*/
37 changes: 12 additions & 25 deletions src/features/auth/api/register.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,18 @@
//import { axios } from '@/lib/axios';

import { UserResponse } from '../types';
import {CreateUserPropsRequest, UserPropsResponse} from '../types';

export type RegisterCredentialsDTO = {
email: string;
password: string;
name: string;
avatarId?: number;
};
import axios from "axios";
import {axiosConfigAuth, baseURL} from "../../../lib/axios";

const hardcodedUserData: UserResponse = {
jwt: 'mock_jwt_token', // Hardcoded JWT token
user: {
id: '1',
email: '[email protected]',
name: 'John Doe'
}
};
export const registerWithEmailAndPassword = (
data: RegisterCredentialsDTO
): Promise<UserResponse> => {
// Return a Promise that immediately resolves with the hardcoded user data
return Promise.resolve(hardcodedUserData);

export const registerWithEmailAndPassword = (data: CreateUserPropsRequest): Promise<UserPropsResponse> => {

return axios.post(`${baseURL}/UserService/users`, data, axiosConfigAuth)
.then(response => response.data)
.catch(error => {
throw error.response.data;
});
};

/*export const registerWithEmailAndPassword = (
data: RegisterCredentialsDTO
): Promise<UserResponse> => {
return axios.post('/auth/register', data);
};*/

38 changes: 24 additions & 14 deletions src/features/auth/routes/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,23 @@ import Button from "../../../components/Elements/Button";
import * as z from 'zod';
import React, {useState} from "react";
import {useLogin} from "../../../lib/auth";
import {hashPassword} from "./index";
import {LoginPropsRequest} from "../types";
import SpinnerComponent from "../../spinner/SpinnerComponent";
import {useNavigate} from "react-router";


const schema = z.object({
email: z.string().min(1, 'Email is required').email('Invalid email format. Please insert valid email.'),
password: z.string().min(1, 'Password is required'),
});
type LoginValues = {
email: string;
password: string;
};


export const Login = () => {
const login = useLogin();
const [values, setValues] = useState<LoginValues>({ email: '', password: '' });
const [values, setValues] = useState<LoginPropsRequest>({ email: '', password: '' });
const [errors, setErrors] = useState<{ [key: string]: string }>({});
const navigate = useNavigate();
const [isSubmitting, setIsSubmitting] = useState(false);

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
Expand All @@ -32,14 +33,20 @@ export const Login = () => {

const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();

setIsSubmitting(true);
try {
schema.parse(values);
values.password = await hashPassword(values.password);
// If validation passes, proceed with form submission
//console.log('Form login submitted:', values);
login.mutate(values);
const request:LoginPropsRequest = {
email: values.email,
password: values.password
}
login.mutate(request, {
onSuccess: () => {
navigate('/');
}
} );
} catch (error) {
setIsSubmitting(false);
if (error instanceof z.ZodError) {
const fieldErrors: { [key: string]: string } = {};
error.errors.forEach(err => {
Expand All @@ -48,6 +55,7 @@ export const Login = () => {
});
setErrors(fieldErrors);
}
console.log("Error: "+error)
}
};

Expand All @@ -71,10 +79,12 @@ export const Login = () => {
</div>

<div className={"pt-5"}>
<Button text={"Sign in"} styleType={"info"} className={"w-full justify-center"} type="submit"/>
{isSubmitting ? (
<SpinnerComponent />
) : (
<Button text={"Sign in"} styleType={"info"} className={"w-full justify-center"} type="submit"/>
)}
</div>


<p className="mt-10 text-center text-sm text-gray-500">
Not a member?{' '}
<Link to={'/auth/register'} className={"text-primaryColor"}>Register a new account here!</Link>
Expand Down
Loading

0 comments on commit c05d411

Please sign in to comment.