Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import { ClickMeetProvider } from "./context/ClickMeetContext";

const App = () => {
return (
<ClickMeetProvider>
<BrowserRouter>
<BrowserRouter>
<ClickMeetProvider>
<Routes>
{routes.map((route) => (
<Route key={route.path} path={route.path} element={route.element} />
))}
</Routes>
</BrowserRouter>
</ClickMeetProvider>
</ClickMeetProvider>
</BrowserRouter>
);
};

Expand Down
8 changes: 5 additions & 3 deletions src/UI/buttons/MenuButton.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ const MenuButton = ({ icon: Icon, text, url }) => {

return (
<li
className="bg-clickmeet-orange text-white flex items-center justify-center p-3 md:py-4 lg:py-5 w-full rounded-xl shadow-md transition-all duration-200 cursor-pointer transform hover:scale-105"
className="bg-clickmeet-orange text-clickmeet-black flex items-center justify-center p-3 md:py-4 lg:py-5 w-full rounded-xl shadow-md transition-all duration-200 cursor-pointer transform hover:scale-105"
onClick={handlerToPage}
>
{Icon && <Icon className="mx-2 md:mx-3 text-lg md:text-xl lg:text-2xl" />}
{Icon && (
<Icon className="mx-2 md:mx-3 text-base md:text-xl lg:text-xl" />
)}
<h1 className="text-base md:text-lg lg:text-xl font-medium">{text}</h1>
</li>
);
};

export default MenuButton;
export default MenuButton;
14 changes: 7 additions & 7 deletions src/UI/forms/login/LoginForm.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import React, { useState } from 'react';
import React, { useState } from "react";
import { FaUserPlus } from "react-icons/fa";
import { FaSignInAlt } from "react-icons/fa";

const LoginForm = ({ onSwitchForm }) => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");

const handleLogin = (e) => {
e.preventDefault();
console.log('Login attempted with:', { email, password });
console.log("Login attempted with:", { email, password });
// TODO: Autentication logic
};

Expand Down Expand Up @@ -40,7 +40,7 @@ const LoginForm = ({ onSwitchForm }) => {
<div className="flex justify-between gap-4 mt-8">
<button
type="submit"
className="flex items-center justify-center text-sm md:text-base gap-2 w-full py-1 md:py-2 md:px-4 bg-orange-400 hover:bg-clickmeet-orange rounded-full text-clickmeet-black font-bold transition-colors"
className="cursor-pointer flex items-center justify-center text-sm md:text-base gap-2 w-full py-1 md:py-2 md:px-4 bg-orange-400 hover:bg-clickmeet-orange rounded-full text-clickmeet-black font-bold transition-colors"
>
<FaSignInAlt size={20} />
Log In
Expand All @@ -49,7 +49,7 @@ const LoginForm = ({ onSwitchForm }) => {
<button
type="button"
onClick={onSwitchForm}
className="flex items-center justify-center text-sm md:text-base gap-2 w-full py-1 md:py-2 md:px-4 bg-orange-400 hover:bg-clickmeet-orange rounded-full text-clickmeet-black font-bold transition-colors"
className="cursor-pointer flex items-center justify-center text-sm md:text-base gap-2 w-full py-1 md:py-2 md:px-4 bg-orange-400 hover:bg-clickmeet-orange rounded-full text-clickmeet-black font-bold transition-colors"
>
<FaUserPlus size={20} />
Sign Up
Expand All @@ -61,4 +61,4 @@ const LoginForm = ({ onSwitchForm }) => {
);
};

export default LoginForm;
export default LoginForm;
22 changes: 22 additions & 0 deletions src/UI/navbar/ClientNavBar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { BiSolidBellRing } from "react-icons/bi";
import { CiHome, CiLogin } from "react-icons/ci";
import { useClickMeet } from "../../context/ClickMeetContext";

const ClientNavBar = () => {
const { goHome, goToLogin } = useClickMeet();
return (
<>
<nav className="bg-clickmeet-black w-screen py-3 text-clickmeet-white md:py-5">
<section className="flex justify-between px-8">
<CiHome onClick={goHome} className="cursor-pointer" />
<div className="flex flex-nowrap">
<CiLogin onClick={goToLogin} className="cursor-pointer mx-3" />
<BiSolidBellRing className="cursor-pointer mx-3" />
</div>
</section>
</nav>
</>
);
};

export default ClientNavBar;
2 changes: 1 addition & 1 deletion src/UI/navbar/Navbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const Navbar = () => {
<nav className="bg-clickmeet-black w-screen py-3 text-clickmeet-white md:py-5">
<section className="flex justify-between px-8">
<CiHome onClick={goHome} className="cursor-pointer" />
<BiSolidBellRing />
<BiSolidBellRing className="cursor-pointer" />
</section>
</nav>
</>
Expand Down
17 changes: 5 additions & 12 deletions src/UI/sections/TitleSection.jsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,17 @@
import React from "react";
import { MdArrowLeft } from "react-icons/md";
import { useNavigate } from "react-router-dom";

import { useClickMeet } from "../../context/ClickMeetContext";

const TitleSection = ({ icon: Icon, text }) => {
const navigate = useNavigate();

const goBack = () => {
navigate(-1);
};
const { goBack } = useClickMeet();

return (
<div className="bg-clickmeet-orange flex items-center justify-center py-2 w-fit px-5 rounded-xl m-auto my-4 cursor-pointer" onClick={goBack}>
<MdArrowLeft
className="text-2xl"
/>
<div className="bg-clickmeet-orange flex items-center justify-center py-2 w-fit px-5 rounded-xl m-auto my-4 ">
<MdArrowLeft className="text-2xl cursor-pointer" onClick={goBack} />
{Icon && <Icon className="mx-2" />}
<h1>{text}</h1>
</div>
);
};

export default TitleSection;
export default TitleSection;
12 changes: 4 additions & 8 deletions src/components/menu/MenuAdmin.jsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
import { FaCalendarCheck, FaUserCircle, FaUserTie } from "react-icons/fa";
import { FaCalendarCheck, FaUserTie } from "react-icons/fa";
import MenuButton from "../../UI/buttons/MenuButton";

const MenuAdmin = ({ title }) => {
return (
<>
<section className="grid place-items-center">
<div className="bg-white p-8 shadow-xl rounded-xl md:w-96">
<h1 className="text-center font-bold md:text-2xl mb-6">{title}</h1>
<ul className="space-y-6">
<h1 className="text-center font-light md:text-xl mb-6">{title}</h1>
<ul className="space-y-6 ">
<MenuButton
icon={FaCalendarCheck}
text={"Upcoming Meetings"}
url={"/admin/upcoming-meetings"}
/>
<MenuButton
icon={FaUserCircle}
text={"Client Metrics"}
url={"/admin/client-metrics"}
/>

<MenuButton
icon={FaUserTie}
text={"Professional Overview"}
Expand Down
8 changes: 2 additions & 6 deletions src/components/menu/MenuClient.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ const MenuClient = ({ title }) => {
<>
<section className="grid place-items-center">
<div className="bg-white p-8 shadow-xl rounded-xl md:w-96 ">
<h1 className="text-center font-bold md:text-2xl mb-6">{title}</h1>
<h1 className="text-center font-light md:text-xl mb-6">{title}</h1>

<ul className="space-y-6">
<MenuButton
icon={FaCalendarCheck}
Expand All @@ -19,11 +20,6 @@ const MenuClient = ({ title }) => {
text={"My Appointments"}
url={"/client/my-appointments"}
/>
<MenuButton
icon={FaCalendar}
text={"Calendar"}
url={"/client/calendar"}
/>
</ul>
</div>
</section>
Expand Down
25 changes: 25 additions & 0 deletions src/context/ClickMeetContext.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { createContext, useContext, useState } from "react";
import { useNavigate } from "react-router-dom";

const ClickMeetContext = createContext();

export const ClickMeetProvider = ({ children }) => {
// Navigation
const navigate = useNavigate();

// Form Data State
const [formData, setFormData] = useState({
firstName: "",
Expand Down Expand Up @@ -110,6 +114,24 @@ export const ClickMeetProvider = ({ children }) => {
setIsClicked(false);
};

// Go back handler

const goBack = () => {
navigate(-1);
setFilterBtn(false);
resetFilters();
};

//Go to Login view
const goToLogin = () => {
navigate("/login");
};

//Go to Home view
const goHome = () => {
navigate("/select-user");
};

// Constants
const months = [
{ value: "1", label: "January" },
Expand Down Expand Up @@ -144,6 +166,9 @@ export const ClickMeetProvider = ({ children }) => {
return (
<ClickMeetContext.Provider
value={{
goHome,
goBack,
goToLogin,
deleteFilterSelection,
editBtn,
handleEditBtn,
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Admin.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const Admin = () => {
<Navbar />
<RolSession rol={"Admin"} />
<Title />
<MenuAdmin title={"Overview and Analytics"} />
<MenuAdmin title={"Meetings and Overview"} />
</>
);
};
Expand Down
4 changes: 2 additions & 2 deletions src/pages/Client.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import MenuClient from "../components/menu/MenuClient";
import Navbar from "../UI/navbar/Navbar";
import ClientNavBar from "../UI/navbar/ClientNavBar";
import RolSession from "../UI/txt/RolSession";
import Title from "../UI/txt/Title";

const Client = () => {
return (
<>
<Navbar />
<ClientNavBar />
<RolSession rol={"Client"} />
<Title />
<MenuClient title={"Welcome, Client :)"} />
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Landing.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const Landing = () => {
<div className="flex flex-col items-center text-center">
<MainTitle />
<button
className="bg-clickmeet-orange text-white py-2 px-6 rounded-full flex items-center transition-transform hover:scale-105"
className="bg-clickmeet-orange cursor-pointer text-white py-2 px-6 rounded-full flex items-center transition-transform hover:scale-105"
onClick={() => navigate("/select-user")}
>
<TiPin className="mr-1" size={18} />
Expand Down
8 changes: 5 additions & 3 deletions src/pages/Login.jsx → src/pages/LoginPage.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { useState } from "react";
import LoginForm from "../UI/forms/login/LoginForm";
import SignUpForm from "../UI/forms/login/SignUpForm";
import Navbar from "../UI/navbar/Navbar";
import Title from "../UI/txt/Title";
import ClientNavBar from "../UI/navbar/ClientNavBar";
import RolSession from "../UI/txt/RolSession";

const LoginPage = () => {
const [showLoginForm, setShowLoginForm] = useState(true);
Expand All @@ -13,7 +14,8 @@ const LoginPage = () => {

return (
<>
<Navbar />
<ClientNavBar />
<RolSession rol={"Client"} />
<Title />
{showLoginForm ? (
<LoginForm onSwitchForm={toggleForm} />
Expand All @@ -24,4 +26,4 @@ const LoginPage = () => {
);
};

export default LoginPage;
export default LoginPage;
4 changes: 2 additions & 2 deletions src/routes.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import ClientMetrics from "./pages/adminViews/ClientMetrics.jsx";
import Client from "./pages/Client.jsx";
import Landing from "./pages/Landing.jsx";
import SelectUser from "./pages/SelectUser.jsx";
import LoginPage from "./pages/Login.jsx";
import LoginPage from "./pages/LoginPage.jsx";
import AppointmentScheduler from "./pages/client/AppointmentScheduler.jsx";
import AppointmentConfirmationPage from "./pages/client/AppointmentConfirmation.jsx";

const routes = [
{ path: "/", element: <Landing /> },
// Login
// Client Login
{ path: "/select-user", element: <SelectUser /> },
{ path: "/login", element: <LoginPage /> }, // TODO: Implement authentication.
// Admin Role
Expand Down
26 changes: 21 additions & 5 deletions src/services/api.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
import axios from 'axios';
import axios from "axios";

const API_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8080/api";
// Axios instance
const api = axios.create({
// eslint-disable-next-line no-undef
baseURL: process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8080/api',
baseURL: API_URL,
headers: {
'Content-Type': 'application/json',
"Content-Type": "application/json",
},
})
});

export default api;
// Iterceptor to add tokens to headers

api.interceptors.request.use(
(config) => {
const token = localStorage.getItem("token");
if (token) {
config.headers["Authorization"] = `Bearer ${token}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);

export default api;
31 changes: 31 additions & 0 deletions src/services/authService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import api from "./api";

const authService = {
// Register a new client
registerClient: async (userData) => {
try {
const res = await api.post("/auth/register", userData);
return res.data;
} catch (error) {
throw error.res?.data || error.message;
}
},
// Login a client
login: async (credentials) => {
try {
const res = await api.post("/auth/login", credentials);
if (res.data.token) {
localStorage.setItem("token", res.data.token);
}
return res.data;
} catch (error) {
throw error.res?.data || error.message;
}
},
// logout a client
logout: () => {
localStorage.removeItem("token");
},
};

export default authService;
4 changes: 4 additions & 0 deletions src/services/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import api from "./api";
import authService from "./authService";

export { api, authService };