Refactor according to ESlint

This commit is contained in:
sosokker 2023-11-23 03:03:19 +07:00
parent 3ad512ab69
commit 135a9aa031
40 changed files with 133 additions and 511 deletions

View File

@ -13,5 +13,6 @@ module.exports = {
plugins: ["react-refresh"], plugins: ["react-refresh"],
rules: { rules: {
"react-refresh/only-export-components": ["warn", { allowConstantExport: true }], "react-refresh/only-export-components": ["warn", { allowConstantExport: true }],
"react/prop-types": 0,
}, },
}; };

View File

@ -1,21 +1,19 @@
import { useEffect } from "react";
import "./App.css"; import "./App.css";
import { Route, Routes, Navigate } from "react-router-dom";
import axios from "axios"; import axios from "axios";
import TestAuth from "./components/testAuth"; import { useEffect } from "react";
import LoginPage from "./components/authentication/LoginPage"; import { Route, Routes, Navigate } from "react-router-dom";
import SignUpPage from "./components/authentication/SignUpPage"; import { LoginPage } from "./components/authentication/LoginPage";
import NavBar from "./components/navigations/Navbar"; import { SignUp } from "./components/authentication/SignUpPage";
import Calendar from "./components/calendar/calendar"; import { NavBar } from "./components/navigations/Navbar";
import KanbanPage from "./components/kanbanBoard/kanbanPage"; import { Calendar } from "./components/calendar/calendar";
import IconSideNav from "./components/navigations/IconSideNav"; import { KanbanPage } from "./components/kanbanBoard/kanbanPage";
import Eisenhower from "./components/EisenhowerMatrix/Eisenhower"; import { SideNav } from "./components/navigations/IconSideNav";
import PrivateRoute from "./PrivateRoute"; import { Eisenhower } from "./components/EisenhowerMatrix/Eisenhower";
import ProfileUpdatePage from "./components/profilePage"; import { PrivateRoute } from "./PrivateRoute";
import Dashboard from "./components/dashboard/dashboard"; import { ProfileUpdatePage } from "./components/profile/profilePage";
import { Dashboard } from "./components/dashboard/dashboard";
import { LandingPage } from "./components/landingPage/LandingPage"; import { LandingPage } from "./components/landingPage/LandingPage";
import PublicRoute from "./PublicRoute"; import { PublicRoute } from "./PublicRoute";
import { useAuth } from "./hooks/AuthHooks"; import { useAuth } from "./hooks/AuthHooks";
const baseURL = import.meta.env.VITE_BASE_URL; const baseURL = import.meta.env.VITE_BASE_URL;
@ -70,7 +68,7 @@ const NonAuthenticatedComponents = () => {
<Route exact path="/login" element={<LoginPage />} /> <Route exact path="/login" element={<LoginPage />} />
</Route> </Route>
<Route exact path="/signup" element={<PublicRoute />}> <Route exact path="/signup" element={<PublicRoute />}>
<Route exact path="/signup" element={<SignUpPage />} /> <Route exact path="/signup" element={<SignUp />} />
</Route> </Route>
<Route path="*" element={<Navigate to="/l" />} /> <Route path="*" element={<Navigate to="/l" />} />
</Routes> </Routes>
@ -81,7 +79,7 @@ const NonAuthenticatedComponents = () => {
const AuthenticatedComponents = () => { const AuthenticatedComponents = () => {
return ( return (
<div className="display: flex"> <div className="display: flex">
<IconSideNav /> <SideNav />
<div className="flex-1 ml-[76px] overflow-hidden"> <div className="flex-1 ml-[76px] overflow-hidden">
<NavBar /> <NavBar />
<div className="overflow-x-auto"> <div className="overflow-x-auto">
@ -90,7 +88,6 @@ const AuthenticatedComponents = () => {
<Route exact path="/tasks" element={<PrivateRoute />}> <Route exact path="/tasks" element={<PrivateRoute />}>
<Route exact path="/tasks" element={<KanbanPage />} /> <Route exact path="/tasks" element={<KanbanPage />} />
</Route> </Route>
<Route path="/testAuth" element={<TestAuth />} />
<Route exact path="/profile" element={<PrivateRoute />}> <Route exact path="/profile" element={<PrivateRoute />}>
<Route exact path="/profile" element={<ProfileUpdatePage />} /> <Route exact path="/profile" element={<ProfileUpdatePage />} />
</Route> </Route>

View File

@ -1,9 +1,7 @@
import { Navigate, Outlet } from "react-router-dom"; import { Navigate, Outlet } from "react-router-dom";
import { useAuth } from "src/hooks/AuthHooks"; import { useAuth } from "src/hooks/AuthHooks";
const PrivateRoute = () => { export const PrivateRoute = () => {
const { isAuthenticated } = useAuth(); const { isAuthenticated } = useAuth();
return isAuthenticated ? <Outlet /> : <Navigate to="/" />; return isAuthenticated ? <Outlet /> : <Navigate to="/" />;
}; };
export default PrivateRoute;

View File

@ -1,9 +1,7 @@
import { Navigate, Outlet } from "react-router-dom"; import { Navigate, Outlet } from "react-router-dom";
import { useAuth } from "src/hooks/AuthHooks"; import { useAuth } from "src/hooks/AuthHooks";
const PublicRoute = () => { export const PublicRoute = () => {
const { isAuthenticated } = useAuth(); const { isAuthenticated } = useAuth();
return isAuthenticated ? <Navigate to="/d" /> : <Outlet />; return isAuthenticated ? <Navigate to="/d" /> : <Outlet />;
}; };
export default PublicRoute;

View File

@ -1,10 +1,10 @@
import axios from "axios"; import axios from "axios";
import axiosInstance from "./AxiosConfig"; import { axiosInstance } from "./AxiosConfig";
const baseURL = import.meta.env.VITE_BASE_URL; const baseURL = import.meta.env.VITE_BASE_URL;
// Function for user login // Function for user login
const apiUserLogin = (data) => { export const apiUserLogin = (data) => {
return axiosInstance return axiosInstance
.post("token/obtain/", data) .post("token/obtain/", data)
.then((response) => { .then((response) => {
@ -19,14 +19,14 @@ const apiUserLogin = (data) => {
}; };
// Function for user logout // Function for user logout
const apiUserLogout = () => { export const apiUserLogout = () => {
axiosInstance.defaults.headers["Authorization"] = ""; // Clear authorization header axiosInstance.defaults.headers["Authorization"] = ""; // Clear authorization header
localStorage.removeItem("access_token"); // Remove access token localStorage.removeItem("access_token"); // Remove access token
localStorage.removeItem("refresh_token"); // Remove refresh token localStorage.removeItem("refresh_token"); // Remove refresh token
}; };
// Function for Google login // Function for Google login
const googleLogin = async (token) => { export const googleLogin = async (token) => {
axios.defaults.withCredentials = true; axios.defaults.withCredentials = true;
let res = await axios.post(`${baseURL}auth/google/`, { let res = await axios.post(`${baseURL}auth/google/`, {
code: token, code: token,
@ -35,20 +35,8 @@ const googleLogin = async (token) => {
return await res; return await res;
}; };
// Function to get 'hello' data
const getGreeting = () => {
return axiosInstance
.get("hello")
.then((response) => {
return response;
})
.catch((error) => {
return error;
});
};
// Function to register // Function to register
const createUser = async (formData) => { export const createUser = async (formData) => {
try { try {
axios.defaults.withCredentials = true; axios.defaults.withCredentials = true;
const response = axios.post(`${baseURL}user/create/`, formData); const response = axios.post(`${baseURL}user/create/`, formData);
@ -58,12 +46,3 @@ const createUser = async (formData) => {
console.log(e); console.log(e);
} }
}; };
// Export the functions and Axios instance
export default {
apiUserLogin,
apiUserLogout,
getGreeting: getGreeting,
googleLogin,
createUser,
};

View File

@ -3,7 +3,7 @@ import { redirect } from "react-router-dom";
const baseURL = import.meta.env.VITE_BASE_URL; const baseURL = import.meta.env.VITE_BASE_URL;
const axiosInstance = axios.create({ export const axiosInstance = axios.create({
baseURL: baseURL, baseURL: baseURL,
timeout: 5000, timeout: 5000,
headers: { headers: {
@ -43,5 +43,3 @@ axiosInstance.interceptors.response.use(
return Promise.reject(error); return Promise.reject(error);
} }
); );
export default axiosInstance;

View File

@ -1,4 +1,4 @@
import axiosInstance from "src/api/AxiosConfig"; import { axiosInstance } from "src/api/AxiosConfig";
const baseURL = import.meta.env.VITE_BASE_URL; const baseURL = import.meta.env.VITE_BASE_URL;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg>

Before

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -1,7 +1,7 @@
import React, { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import { FiAlertCircle, FiClock, FiXCircle, FiCheckCircle } from "react-icons/fi"; import { FiAlertCircle, FiClock, FiXCircle, FiCheckCircle } from "react-icons/fi";
import { readTodoTasks } from "../../api/TaskApi"; import { readTodoTasks } from "../../api/TaskApi";
import axiosInstance from "src/api/AxiosConfig"; import { axiosInstance } from "src/api/AxiosConfig";
function EachBlog({ name, colorCode, contentList, icon }) { function EachBlog({ name, colorCode, contentList, icon }) {
const [tasks, setTasks] = useState(contentList); const [tasks, setTasks] = useState(contentList);
@ -55,7 +55,7 @@ function EachBlog({ name, colorCode, contentList, icon }) {
); );
} }
function Eisenhower() { export function Eisenhower() {
const [tasks, setTasks] = useState([]); const [tasks, setTasks] = useState([]);
useEffect(() => { useEffect(() => {
@ -108,5 +108,3 @@ function Eisenhower() {
</div> </div>
); );
} }
export default Eisenhower;

View File

@ -1,24 +1,16 @@
import { useEffect, useState } from "react";
import { useNavigate, redirect } from "react-router-dom"; import { useNavigate, redirect } from "react-router-dom";
import { useGoogleLogin } from "@react-oauth/google"; import { useGoogleLogin } from "@react-oauth/google";
import { useCallback } from "react"; import { useCallback, useState } from "react";
import Particles from "react-tsparticles"; import Particles from "react-tsparticles";
import { loadFull } from "tsparticles"; import { loadFull } from "tsparticles";
import refreshAccessToken from "./refreshAcessToken";
import axiosapi from "../../api/AuthenticationApi";
import { FcGoogle } from "react-icons/fc"; import { FcGoogle } from "react-icons/fc";
import { useAuth } from "src/hooks/AuthHooks"; import { useAuth } from "src/hooks/AuthHooks";
import { googleLogin, apiUserLogin } from "src/api/AuthenticationApi";
function LoginPage() { export function LoginPage() {
const { setIsAuthenticated } = useAuth(); const { setIsAuthenticated } = useAuth();
const Navigate = useNavigate(); const Navigate = useNavigate();
useEffect(() => {
if (!refreshAccessToken()) {
Navigate("/");
}
}, []);
const [email, setEmail] = useState(""); const [email, setEmail] = useState("");
const [password, setPassword] = useState(""); const [password, setPassword] = useState("");
@ -33,16 +25,14 @@ function LoginPage() {
event.preventDefault(); event.preventDefault();
// Send a POST request to the authentication API // Send a POST request to the authentication API
axiosapi apiUserLogin({
.apiUserLogin({ email: email,
email: email, password: password,
password: password, })
})
.then((res) => { .then((res) => {
// On successful login, store tokens and set the authorization header // On successful login, store tokens and set the authorization header
localStorage.setItem("access_token", res.data.access); localStorage.setItem("access_token", res.data.access);
localStorage.setItem("refresh_token", res.data.refresh); localStorage.setItem("refresh_token", res.data.refresh);
axiosapi.axiosInstance.defaults.headers["Authorization"] = "Bearer " + res.data.access;
setIsAuthenticated(true); setIsAuthenticated(true);
redirect("/"); redirect("/");
}) })
@ -57,7 +47,7 @@ function LoginPage() {
redirect_uri: "postmessage", redirect_uri: "postmessage",
onSuccess: async (response) => { onSuccess: async (response) => {
try { try {
const loginResponse = await axiosapi.googleLogin(response.code); const loginResponse = await googleLogin(response.code);
if (loginResponse && loginResponse.data) { if (loginResponse && loginResponse.data) {
const { access_token, refresh_token } = loginResponse.data; const { access_token, refresh_token } = loginResponse.data;
@ -76,14 +66,9 @@ function LoginPage() {
/* Particles Loader*/ /* Particles Loader*/
} }
const particlesInit = useCallback(async (engine) => { const particlesInit = useCallback(async (engine) => {
console.log(engine);
await loadFull(engine); await loadFull(engine);
}, []); }, []);
const particlesLoaded = useCallback(async (container) => {
console.log(container);
}, []);
return ( return (
<div data-theme="night" className="h-screen flex items-center justify-center"> <div data-theme="night" className="h-screen flex items-center justify-center">
{/* Particles Container */} {/* Particles Container */}
@ -91,7 +76,6 @@ function LoginPage() {
<Particles <Particles
id="particles" id="particles"
init={particlesInit} init={particlesInit}
loaded={particlesLoaded}
className="-z-10" className="-z-10"
options={{ options={{
fpsLimit: 240, fpsLimit: 240,
@ -214,5 +198,3 @@ function LoginPage() {
</div> </div>
); );
} }
export default LoginPage;

View File

@ -1,21 +1,18 @@
import React, { useState } from "react"; import { useState } from "react";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import axiosapi from "../../api/AuthenticationApi";
import { useCallback } from "react"; import { useCallback } from "react";
import Particles from "react-tsparticles"; import Particles from "react-tsparticles";
import { loadFull } from "tsparticles"; import { loadFull } from "tsparticles";
import { FcGoogle } from "react-icons/fc"; import { FcGoogle } from "react-icons/fc";
import { useGoogleLogin } from "@react-oauth/google"; import { useGoogleLogin } from "@react-oauth/google";
import { useAuth } from "src/hooks/AuthHooks";
import { createUser, googleLogin } from "src/api/AuthenticationApi";
function Copyright(props) { function Copyright(props) {
return ( return (
<div className="text-center text-sm text-gray-500" {...props}> <div className="text-center text-sm text-gray-500" {...props}>
{"Copyright © "} {"Copyright © "}
<a <a href="https://github.com/TurTaskProject/TurTaskWeb" className="text-blue-500 hover:underline">
href="https://github.com/TurTaskProject/TurTaskWeb"
className="text-blue-500 hover:underline"
>
TurTask TurTask
</a>{" "} </a>{" "}
{new Date().getFullYear()} {new Date().getFullYear()}
@ -24,8 +21,9 @@ function Copyright(props) {
); );
} }
export default function SignUp() { export function SignUp() {
const Navigate = useNavigate(); const Navigate = useNavigate();
const { setIsAuthenticated } = useAuth;
const [formData, setFormData] = useState({ const [formData, setFormData] = useState({
email: "", email: "",
@ -41,7 +39,7 @@ export default function SignUp() {
setError(null); setError(null);
try { try {
axiosapi.createUser(formData); createUser(formData);
} catch (error) { } catch (error) {
console.error("Error creating user:", error); console.error("Error creating user:", error);
setError("Registration failed. Please try again."); setError("Registration failed. Please try again.");
@ -54,26 +52,20 @@ export default function SignUp() {
const handleChange = (e) => { const handleChange = (e) => {
const { name, value } = e.target; const { name, value } = e.target;
setFormData({ ...formData, [name]: value }); setFormData({ ...formData, [name]: value });
console.log(formData);
}; };
{ {
/* Particles Loader*/ /* Particles Loader*/
} }
const particlesInit = useCallback(async (engine) => { const particlesInit = useCallback(async (engine) => {
console.log(engine);
await loadFull(engine); await loadFull(engine);
}, []); }, []);
const particlesLoaded = useCallback(async (container) => {
console.log(container);
}, []);
const googleLoginImplicit = useGoogleLogin({ const googleLoginImplicit = useGoogleLogin({
flow: "auth-code", flow: "auth-code",
redirect_uri: "postmessage", redirect_uri: "postmessage",
onSuccess: async (response) => { onSuccess: async (response) => {
try { try {
const loginResponse = await axiosapi.googleLogin(response.code); const loginResponse = await googleLogin(response.code);
if (loginResponse && loginResponse.data) { if (loginResponse && loginResponse.data) {
const { access_token, refresh_token } = loginResponse.data; const { access_token, refresh_token } = loginResponse.data;
@ -91,16 +83,12 @@ export default function SignUp() {
}); });
return ( return (
<div <div data-theme="night" className="h-screen flex items-center justify-center">
data-theme="night"
className="h-screen flex items-center justify-center"
>
{/* Particles Container */} {/* Particles Container */}
<div style={{ width: "0%", height: "100vh" }}> <div style={{ width: "0%", height: "100vh" }}>
<Particles <Particles
id="particles" id="particles"
init={particlesInit} init={particlesInit}
loaded={particlesLoaded}
className="-z-10" className="-z-10"
options={{ options={{
fpsLimit: 240, fpsLimit: 240,
@ -179,13 +167,7 @@ export default function SignUp() {
Email<span className="text-red-500 text-bold">*</span> Email<span className="text-red-500 text-bold">*</span>
</p> </p>
</label> </label>
<input <input className="input" type="email" id="email" placeholder="Enter your email" onChange={handleChange} />
className="input"
type="email"
id="email"
placeholder="Enter your email"
onChange={handleChange}
/>
</div> </div>
{/* Username Input */} {/* Username Input */}
<div className="form-control"> <div className="form-control">
@ -225,17 +207,13 @@ export default function SignUp() {
</button> </button>
<div className="divider">OR</div> <div className="divider">OR</div>
{/* Login with Google Button */} {/* Login with Google Button */}
<button <button className="btn btn-outline btn-secondary w-full " onClick={() => googleLoginImplicit()}>
className="btn btn-outline btn-secondary w-full " <FcGoogle className="rounded-full bg-white" />
onClick={() => googleLoginImplicit()} Login with Google
>
<FcGoogle className="rounded-full bg-white"/>Login with Google
</button> </button>
{/* Already have an account? */} {/* Already have an account? */}
<div className="text-blue-500 flex justify-center text-sm"> <div className="text-blue-500 flex justify-center text-sm">
<a href="login"> <a href="login">Already have an account?</a>
Already have an account?
</a>
</div> </div>
<Copyright /> <Copyright />
</div> </div>

View File

@ -1,39 +0,0 @@
import axios from "axios";
const baseURL = import.meta.env.VITE_BASE_URL;
async function refreshAccessToken() {
const refresh_token = localStorage.getItem("refresh_token");
const access_token = localStorage.getItem("access_token");
if (access_token) {
return true;
}
if (!refresh_token) {
return false;
}
const refreshUrl = `${baseURL}token/refresh/`;
try {
const response = await axios.post(refreshUrl, { refresh: refresh_token });
if (response.status === 200) {
// Successful refresh - save the new access token and refresh token
const newAccessToken = response.data.access;
const newRefreshToken = response.data.refresh;
localStorage.setItem("access_token", newAccessToken);
localStorage.setItem("refresh_token", newRefreshToken);
return true;
} else {
return false;
}
} catch (error) {
return false;
}
}
export default refreshAccessToken;

View File

@ -1,9 +1,9 @@
import { readTodoTasks } from "../../api/TaskApi"; import { readTodoTasks } from "src/api/TaskApi";
let eventGuid = 0; let eventGuid = 0;
const mapResponseToEvents = response => { const mapResponseToEvents = (response) => {
return response.map(item => ({ return response.map((item) => ({
id: item.id, id: item.id,
title: item.title, title: item.title,
start: item.start_event, start: item.start_event,

View File

@ -5,9 +5,9 @@ import dayGridPlugin from "@fullcalendar/daygrid";
import timeGridPlugin from "@fullcalendar/timegrid"; import timeGridPlugin from "@fullcalendar/timegrid";
import interactionPlugin from "@fullcalendar/interaction"; import interactionPlugin from "@fullcalendar/interaction";
import { getEvents, createEventId } from "./TaskDataHandler"; import { getEvents, createEventId } from "./TaskDataHandler";
import axiosInstance from "src/api/AxiosConfig"; import { axiosInstance } from "src/api/AxiosConfig";
export default class Calendar extends React.Component { export class Calendar extends React.Component {
state = { state = {
weekendsVisible: true, weekendsVisible: true,
currentEvents: [], currentEvents: [],

View File

@ -1,6 +1,6 @@
import { AreaChart, Title } from "@tremor/react"; import { AreaChart, Title } from "@tremor/react";
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import axiosInstance from "src/api/AxiosConfig"; import { axiosInstance } from "src/api/AxiosConfig";
export const AreaChartGraph = () => { export const AreaChartGraph = () => {
const [areaChartDataArray, setAreaChartDataArray] = useState([]); const [areaChartDataArray, setAreaChartDataArray] = useState([]);

View File

@ -1,6 +1,6 @@
import { BarChart, Title } from "@tremor/react"; import { BarChart, Title } from "@tremor/react";
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import axiosInstance from "src/api/AxiosConfig"; import { axiosInstance } from "src/api/AxiosConfig";
export const BarChartGraph = () => { export const BarChartGraph = () => {
const [barchartDataArray, setBarChartDataArray] = useState([]); const [barchartDataArray, setBarChartDataArray] = useState([]);

View File

@ -1,8 +1,8 @@
import { DonutChart } from "@tremor/react"; import { DonutChart } from "@tremor/react";
import axiosInstance from "src/api/AxiosConfig"; import { axiosInstance } from "src/api/AxiosConfig";
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
export default function DonutChartGraph() { export function DonutChartGraph() {
const [donutData, setDonutData] = useState([]); const [donutData, setDonutData] = useState([]);
useEffect(() => { useEffect(() => {

View File

@ -1,8 +1,8 @@
import { BadgeDelta, Card, Flex, Metric, ProgressBar, Text } from "@tremor/react"; import { BadgeDelta, Card, Flex, Metric, ProgressBar, Text } from "@tremor/react";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import axiosInstance from "src/api/AxiosConfig"; import { axiosInstance } from "src/api/AxiosConfig";
export default function KpiCard() { export function KpiCard() {
const [kpiCardData, setKpiCardData] = useState({ const [kpiCardData, setKpiCardData] = useState({
completedThisWeek: 0, completedThisWeek: 0,
completedLastWeek: 0, completedLastWeek: 0,

View File

@ -1,8 +1,8 @@
import { Card, Flex, ProgressCircle } from "@tremor/react"; import { Card, Flex, ProgressCircle } from "@tremor/react";
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import axiosInstance from "src/api/AxiosConfig"; import { axiosInstance } from "src/api/AxiosConfig";
export default function ProgressCircleChart() { export function ProgressCircleChart() {
const [progressData, setProgressData] = useState(0); const [progressData, setProgressData] = useState(0);
useEffect(() => { useEffect(() => {

View File

@ -1,11 +1,11 @@
import { Card, Grid, Tab, TabGroup, TabList, TabPanel, TabPanels, Text, Title, Legend } from "@tremor/react"; import { Card, Grid, Tab, TabGroup, TabList, TabPanel, TabPanels, Text, Title, Legend } from "@tremor/react";
import KpiCard from "./KpiCard"; import { KpiCard } from "./KpiCard";
import { BarChartGraph } from "./Barchart"; import { BarChartGraph } from "./Barchart";
import DonutChartGraph from "./DonutChart"; import { DonutChartGraph } from "./DonutChart";
import { AreaChartGraph } from "./Areachart"; import { AreaChartGraph } from "./Areachart";
import ProgressCircleChart from "./ProgressCircle"; import { ProgressCircleChart } from "./ProgressCircle";
export default function Dashboard() { export function Dashboard() {
return ( return (
<div className="flex flex-col p-12"> <div className="flex flex-col p-12">
<div> <div>

View File

@ -3,13 +3,13 @@ import { BsFillTrashFill } from "react-icons/bs";
import { AiOutlinePlusCircle } from "react-icons/ai"; import { AiOutlinePlusCircle } from "react-icons/ai";
import { CSS } from "@dnd-kit/utilities"; import { CSS } from "@dnd-kit/utilities";
import { useMemo, useState } from "react"; import { useMemo, useState } from "react";
import TaskCard from "./taskCard"; import { TaskCard } from "./taskCard";
function ColumnContainer({ column, deleteColumn, updateColumn, createTask, tasks, deleteTask, updateTask }) { export function ColumnContainer({ column, deleteColumn, updateColumn, createTask, tasks, deleteTask, updateTask }) {
const [editMode, setEditMode] = useState(false); const [editMode, setEditMode] = useState(false);
const tasksIds = useMemo(() => { const tasksIds = useMemo(() => {
return tasks.map(task => task.id); return tasks.map((task) => task.id);
}, [tasks]); }, [tasks]);
const { setNodeRef, attributes, listeners, transform, transition, isDragging } = useSortable({ const { setNodeRef, attributes, listeners, transform, transition, isDragging } = useSortable({
@ -78,12 +78,12 @@ function ColumnContainer({ column, deleteColumn, updateColumn, createTask, tasks
<input <input
className="bg-gray-200 focus:border-blue-500 border rounded-md outline-none px-2" className="bg-gray-200 focus:border-blue-500 border rounded-md outline-none px-2"
value={column.title} value={column.title}
onChange={e => updateColumn(column.id, e.target.value)} onChange={(e) => updateColumn(column.id, e.target.value)}
autoFocus autoFocus
onBlur={() => { onBlur={() => {
setEditMode(false); setEditMode(false);
}} }}
onKeyDown={e => { onKeyDown={(e) => {
if (e.key !== "Enter") return; if (e.key !== "Enter") return;
setEditMode(false); setEditMode(false);
}} }}
@ -109,7 +109,7 @@ function ColumnContainer({ column, deleteColumn, updateColumn, createTask, tasks
{/* Column task container */} {/* Column task container */}
<div className="flex flex-grow flex-col gap-2 p-1 overflow-x-hidden overflow-y-auto"> <div className="flex flex-grow flex-col gap-2 p-1 overflow-x-hidden overflow-y-auto">
<SortableContext items={tasksIds}> <SortableContext items={tasksIds}>
{tasks.map(task => ( {tasks.map((task) => (
<TaskCard key={task.id} task={task} deleteTask={deleteTask} updateTask={updateTask} /> <TaskCard key={task.id} task={task} deleteTask={deleteTask} updateTask={updateTask} />
))} ))}
</SortableContext> </SortableContext>
@ -126,5 +126,3 @@ function ColumnContainer({ column, deleteColumn, updateColumn, createTask, tasks
</div> </div>
); );
} }
export default ColumnContainer;

View File

@ -1,6 +1,6 @@
import ColumnContainer from "./columnContainer"; import { ColumnContainer } from "./columnContainer";
function ColumnContainerCard({ column, deleteColumn, updateColumn, createTask, tasks, deleteTask, updateTask }) { export function ColumnContainerCard({ column, deleteColumn, updateColumn, createTask, tasks, deleteTask, updateTask }) {
return ( return (
<div className="card bg-[#f1f2f4] shadow p-1 my-2 border-2"> <div className="card bg-[#f1f2f4] shadow p-1 my-2 border-2">
<ColumnContainer <ColumnContainer
@ -15,5 +15,3 @@ function ColumnContainerCard({ column, deleteColumn, updateColumn, createTask, t
</div> </div>
); );
} }
export default ColumnContainerCard;

View File

@ -1,13 +1,12 @@
import { useMemo, useState, useEffect } from "react"; import { useMemo, useState, useEffect } from "react";
import ColumnContainerCard from "./columnContainerWrapper"; import { ColumnContainerCard } from "./columnContainerWrapper";
import { DndContext, DragOverlay, PointerSensor, useSensor, useSensors } from "@dnd-kit/core"; import { DndContext, DragOverlay, PointerSensor, useSensor, useSensors } from "@dnd-kit/core";
import { SortableContext, arrayMove } from "@dnd-kit/sortable"; import { SortableContext, arrayMove } from "@dnd-kit/sortable";
import { createPortal } from "react-dom"; import { createPortal } from "react-dom";
import TaskCard from "./taskCard"; import { TaskCard } from "./taskCard";
import { AiOutlinePlusCircle } from "react-icons/ai"; import { axiosInstance } from "src/api/AxiosConfig";
import axiosInstance from "src/api/AxiosConfig";
function KanbanBoard() { export function KanbanBoard() {
const [columns, setColumns] = useState([]); const [columns, setColumns] = useState([]);
const columnsId = useMemo(() => columns.map((col) => col.id), [columns]); const columnsId = useMemo(() => columns.map((col) => col.id), [columns]);
const [boardId, setBoardData] = useState(); const [boardId, setBoardData] = useState();
@ -26,40 +25,6 @@ function KanbanBoard() {
}) })
); );
// Example
// {
// "id": 95,
// "title": "Test Todo",
// "notes": "Test TodoTest TodoTest Todo",
// "importance": 1,
// "difficulty": 1,
// "challenge": false,
// "fromSystem": false,
// "creation_date": "2023-11-20T19:50:16.369308Z",
// "last_update": "2023-11-20T19:50:16.369308Z",
// "is_active": true,
// "is_full_day_event": false,
// "start_event": "2023-11-20T19:49:49Z",
// "end_event": "2023-11-23T18:00:00Z",
// "google_calendar_id": null,
// "completed": true,
// "completion_date": "2023-11-20T19:50:16.369308Z",
// "priority": 3,
// "user": 1,
// "list_board": 1,
// "tags": []
// }
// ]
// [
// {
// "id": 8,
// "name": "test",
// "position": 2,
// "board": 3
// }
// ]
useEffect(() => { useEffect(() => {
const fetchData = async () => { const fetchData = async () => {
try { try {
@ -73,7 +38,6 @@ function KanbanBoard() {
difficulty: task.difficulty, difficulty: task.difficulty,
notes: task.notes, notes: task.notes,
importance: task.importance, importance: task.importance,
difficulty: task.difficulty,
challenge: task.challenge, challenge: task.challenge,
fromSystem: task.fromSystem, fromSystem: task.fromSystem,
creation_date: task.creation_date, creation_date: task.creation_date,
@ -149,31 +113,6 @@ function KanbanBoard() {
))} ))}
</SortableContext> </SortableContext>
</div> </div>
{/* create new column */}
<button
onClick={() => {
createNewColumn();
}}
className="
h-[60px]
w-[268px]
max-w-[268px]
cursor-pointer
rounded-xl
bg-[#f1f2f4]
border-2
p-4
hover:bg-gray-200
flex
gap-2
my-2
bg-opacity-60
">
<div className="my-1">
<AiOutlinePlusCircle />
</div>
Add Column
</button>
</div> </div>
{createPortal( {createPortal(
@ -409,10 +348,4 @@ function KanbanBoard() {
}); });
} }
} }
function generateId() {
return Math.floor(Math.random() * 10001);
}
} }
export default KanbanBoard;

View File

@ -1,12 +1,12 @@
import KanbanBoard from "./kanbanBoard"; import { KanbanBoard } from "./kanbanBoard";
import React, { useState } from 'react'; import { useState } from "react";
const KanbanPage = () => { export const KanbanPage = () => {
const [activeTab, setActiveTab] = useState('kanban'); const [activeTab, setActiveTab] = useState("kanban");
const handleTabClick = (tabId) => { const handleTabClick = (tabId) => {
setActiveTab(tabId); setActiveTab(tabId);
}; };
return ( return (
<div className="flex flex-col"> <div className="flex flex-col">
@ -29,10 +29,7 @@ const KanbanPage = () => {
</div> </div>
</div> </div>
<KanbanBoard /> <KanbanBoard />
<div className="flex justify-center border-2 "> <div className="flex justify-center border-2 "></div>
</div>
</div> </div>
); );
}; };
export default KanbanPage;

View File

@ -2,9 +2,9 @@ import { useState } from "react";
import { BsFillTrashFill } from "react-icons/bs"; import { BsFillTrashFill } from "react-icons/bs";
import { useSortable } from "@dnd-kit/sortable"; import { useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities"; import { CSS } from "@dnd-kit/utilities";
import TaskDetailModal from "./taskDetailModal"; import { TaskDetailModal } from "./taskDetailModal";
function TaskCard({ task, deleteTask, updateTask}) { export function TaskCard({ task, deleteTask, updateTask }) {
const [mouseIsOver, setMouseIsOver] = useState(false); const [mouseIsOver, setMouseIsOver] = useState(false);
const { setNodeRef, attributes, listeners, transform, transition, isDragging } = useSortable({ const { setNodeRef, attributes, listeners, transform, transition, isDragging } = useSortable({
@ -15,7 +15,6 @@ function TaskCard({ task, deleteTask, updateTask}) {
}, },
}); });
const style = { const style = {
transition, transition,
transform: CSS.Transform.toString(transform), transform: CSS.Transform.toString(transform),
@ -79,5 +78,3 @@ function TaskCard({ task, deleteTask, updateTask}) {
</div> </div>
); );
} }
export default TaskCard;

View File

@ -1,9 +1,9 @@
import React, { useState } from "react"; import { useState } from "react";
import { FaTasks, FaRegListAlt } from "react-icons/fa"; import { FaTasks, FaRegListAlt } from "react-icons/fa";
import { FaPlus } from "react-icons/fa6"; import { FaPlus } from "react-icons/fa6";
import { TbChecklist } from "react-icons/tb"; import { TbChecklist } from "react-icons/tb";
function TaskDetailModal({ title, description, tags, difficulty, challenge, importance, taskId }) { export function TaskDetailModal({ title, description, tags, difficulty, challenge, importance, taskId }) {
const [isChallengeChecked, setChallengeChecked] = useState(challenge); const [isChallengeChecked, setChallengeChecked] = useState(challenge);
const [isImportantChecked, setImportantChecked] = useState(importance); const [isImportantChecked, setImportantChecked] = useState(importance);
const [currentDifficulty, setCurrentDifficulty] = useState(difficulty); const [currentDifficulty, setCurrentDifficulty] = useState(difficulty);
@ -28,7 +28,8 @@ function TaskDetailModal({ title, description, tags, difficulty, challenge, impo
<div className="flex flex-col"> <div className="flex flex-col">
<h3 className="font-bold text-lg"> <h3 className="font-bold text-lg">
<span className="flex gap-2"> <span className="flex gap-2">
{<FaTasks className="my-2" />}{title} {<FaTasks className="my-2" />}
{title}
</span> </span>
</h3> </h3>
<p className="text-xs">{title}</p> <p className="text-xs">{title}</p>
@ -45,13 +46,13 @@ function TaskDetailModal({ title, description, tags, difficulty, challenge, impo
<ul tabIndex={0} className="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-52"> <ul tabIndex={0} className="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-52">
<li> <li>
<a> <a>
<input type="checkbox" checked="checked" className="checkbox checkbox-sm"/> <input type="checkbox" checked="checked" className="checkbox checkbox-sm" />
Item 2 Item 2
</a> </a>
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
<div className="flex flex-nowrap overflow-x-auto"></div> <div className="flex flex-nowrap overflow-x-auto"></div>
</div> </div>
@ -144,5 +145,3 @@ function TaskDetailModal({ title, description, tags, difficulty, challenge, impo
</dialog> </dialog>
); );
} }
export default TaskDetailModal;

View File

@ -1,9 +1,9 @@
import { useState } from "react"; import { useState } from "react";
import { AiOutlineHome, AiOutlineSchedule, AiOutlineUnorderedList, AiOutlinePieChart } from "react-icons/ai"; import { AiOutlineHome, AiOutlineSchedule, AiOutlineUnorderedList } from "react-icons/ai";
import { PiStepsDuotone } from "react-icons/pi"; import { PiStepsDuotone } from "react-icons/pi";
import { IoSettingsOutline } from "react-icons/io5"; import { IoSettingsOutline } from "react-icons/io5";
import { AnimatePresence, motion } from "framer-motion"; import { AnimatePresence, motion } from "framer-motion";
import { Link, useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
const menuItems = [ const menuItems = [
{ id: 0, path: "/", icon: <AiOutlineHome /> }, { id: 0, path: "/", icon: <AiOutlineHome /> },
@ -13,20 +13,12 @@ const menuItems = [
{ id: 4, path: "/priority", icon: <PiStepsDuotone /> }, { id: 4, path: "/priority", icon: <PiStepsDuotone /> },
]; ];
const IconSideNav = () => { export const SideNav = () => {
return (
<div className="bg-slate-900 text-slate-100 flex">
<SideNav />
</div>
);
};
const SideNav = () => {
const [selected, setSelected] = useState(0); const [selected, setSelected] = useState(0);
return ( return (
<nav className="bg-slate-950 p-4 flex flex-col items-center gap-2 h-full fixed top-0 left-0 z-50"> <nav className="bg-slate-950 p-4 flex flex-col items-center gap-2 h-full fixed top-0 left-0 z-50">
{menuItems.map(item => ( {menuItems.map((item) => (
<NavItem <NavItem
key={item.id} key={item.id}
icon={item.icon} icon={item.icon}
@ -65,5 +57,3 @@ const NavItem = ({ icon, selected, id, setSelected, logo, path }) => {
</motion.button> </motion.button>
); );
}; };
export default IconSideNav;

View File

@ -1,5 +1,5 @@
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import axiosapi from "../../api/AuthenticationApi"; import { apiUserLogout } from "src/api/AuthenticationApi";
import { useAuth } from "src/hooks/AuthHooks"; import { useAuth } from "src/hooks/AuthHooks";
const settings = { const settings = {
@ -7,13 +7,12 @@ const settings = {
Account: "/account", Account: "/account",
}; };
function NavBar() { export function NavBar() {
const Navigate = useNavigate(); const Navigate = useNavigate();
const { isAuthenticated, setIsAuthenticated } = useAuth(); const { isAuthenticated, setIsAuthenticated } = useAuth();
console.log(isAuthenticated);
const logout = () => { const logout = () => {
axiosapi.apiUserLogout(); apiUserLogout();
setIsAuthenticated(false); setIsAuthenticated(false);
Navigate("/"); Navigate("/");
}; };
@ -66,4 +65,3 @@ function NavBar() {
</div> </div>
); );
} }
export default NavBar;

View File

@ -1,7 +1,7 @@
import React, { useState, useRef } from "react"; import { useState, useRef } from "react";
import { ApiUpdateUserProfile } from "../api/UserProfileApi"; import { ApiUpdateUserProfile } from "src/api/UserProfileApi";
function ProfileUpdateComponent() { export function ProfileUpdateComponent() {
const [file, setFile] = useState(null); const [file, setFile] = useState(null);
const [username, setUsername] = useState(""); const [username, setUsername] = useState("");
const [fullName, setFullName] = useState(""); const [fullName, setFullName] = useState("");
@ -15,7 +15,7 @@ function ProfileUpdateComponent() {
} }
}; };
const handleFileChange = e => { const handleFileChange = (e) => {
const selectedFile = e.target.files[0]; const selectedFile = e.target.files[0];
if (selectedFile) { if (selectedFile) {
setFile(selectedFile); setFile(selectedFile);
@ -66,7 +66,7 @@ function ProfileUpdateComponent() {
placeholder="Enter your username" placeholder="Enter your username"
className="input w-full" className="input w-full"
value={username} value={username}
onChange={e => setUsername(e.target.value)} onChange={(e) => setUsername(e.target.value)}
/> />
</div> </div>
@ -78,7 +78,7 @@ function ProfileUpdateComponent() {
placeholder="Enter your full name" placeholder="Enter your full name"
className="input w-full" className="input w-full"
value={fullName} value={fullName}
onChange={e => setFullName(e.target.value)} onChange={(e) => setFullName(e.target.value)}
/> />
</div> </div>
@ -89,7 +89,7 @@ function ProfileUpdateComponent() {
placeholder="Tell us about yourself" placeholder="Tell us about yourself"
className="textarea w-full h-32" className="textarea w-full h-32"
value={about} value={about}
onChange={e => setAbout(e.target.value)} onChange={(e) => setAbout(e.target.value)}
/> />
</div> </div>
@ -100,5 +100,3 @@ function ProfileUpdateComponent() {
</div> </div>
); );
} }
export default ProfileUpdateComponent;

View File

@ -1,7 +1,6 @@
import * as React from "react"; import { ProfileUpdateComponent } from "./ProfileUpdateComponent";
import ProfileUpdateComponent from "./ProfileUpdateComponent";
function ProfileUpdatePage() { export function ProfileUpdatePage() {
return ( return (
<div> <div>
<div className="stats shadow mt-3"> <div className="stats shadow mt-3">
@ -47,7 +46,7 @@ function ProfileUpdatePage() {
</div> </div>
</div> </div>
<div className="stat-desc py-2">3213/321312321 points</div> <div className="stat-desc py-2">3213/321312321 points</div>
<progress class="progress progress-info w-36" value="10" max="100"></progress> <progress className="progress progress-info w-36" value="10" max="100"></progress>
</div> </div>
<div className="stat"> <div className="stat">
@ -75,10 +74,10 @@ function ProfileUpdatePage() {
</div> </div>
<div className="card bg-base-100 shadow"> <div className="card bg-base-100 shadow">
<div class="card-body"> <div className="card-body">
<h2 class="card-title">About me</h2> <h2 className="card-title">About me</h2>
<div class="card-actions justify-end"></div> <div className="card-actions justify-end"></div>
<textarea class="textarea textarea-bordered textarea-lg w-full" disabled> <textarea className="textarea textarea-bordered textarea-lg w-full" disabled>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nostrum dolores recusandae, officiis consequuntur Lorem ipsum dolor sit amet consectetur adipisicing elit. Nostrum dolores recusandae, officiis consequuntur
nam, non ab commodi totam mollitia iusto nemo voluptatum error aliquam similique perspiciatis, eligendi nam, non ab commodi totam mollitia iusto nemo voluptatum error aliquam similique perspiciatis, eligendi
nulla. Animi, sit? nulla. Animi, sit?
@ -89,31 +88,31 @@ function ProfileUpdatePage() {
<div className="grid grid-cols-2 grid-rows-2 gap-4 my-2"> <div className="grid grid-cols-2 grid-rows-2 gap-4 my-2">
<div className="col-span-full"> <div className="col-span-full">
<div className="card bg-base-100 shadow"> <div className="card bg-base-100 shadow">
<div class="card-body"> <div className="card-body">
<h2 class="card-title">Overall Statistics</h2> <h2 className="card-title">Overall Statistics</h2>
<div class="card-actions justify-end"></div> <div className="card-actions justify-end"></div>
</div> </div>
</div> </div>
</div> </div>
<div className="col-start-2 row-start-2"> <div className="col-start-2 row-start-2">
<div className="card bg-base-100 shadow"> <div className="card bg-base-100 shadow">
<div class="card-body"> <div className="card-body">
<h2 class="card-title">Achievements</h2> <h2 className="card-title">Achievements</h2>
<div class="card-actions justify-end"></div> <div className="card-actions justify-end"></div>
</div> </div>
</div> </div>
</div> </div>
<div className="col-start-1 row-start-2"> <div className="col-start-1 row-start-2">
<div className="card bg-base-100 shadow"> <div className="card bg-base-100 shadow">
<div class="card-body"> <div className="card-body">
<h2 class="card-title">Friends</h2> <h2 className="card-title">Friends</h2>
<div class="card-actions justify-end"></div> <div className="card-actions justify-end"></div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="fixed bottom-4 right-4"> <div className="fixed bottom-4 right-4">
<ul className="menu menu-horizontal bg-base-200 rounded-box"> <ul className="menu menu-horizontal bg-base-200 rounded-box">
<li> <li>
<a onClick={() => document.getElementById("my_modal_4").showModal()}> <a onClick={() => document.getElementById("my_modal_4").showModal()}>
@ -136,11 +135,10 @@ function ProfileUpdatePage() {
<div className="modal-box w-11/12 max-w-5xl flex flex-col"> <div className="modal-box w-11/12 max-w-5xl flex flex-col">
<form method="dialog"> <form method="dialog">
<ProfileUpdateComponent /> <ProfileUpdateComponent />
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"></button> <button className="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"></button>
</form> </form>
</div> </div>
</dialog> </dialog>
</div> </div>
); );
} }
export default ProfileUpdatePage;

View File

@ -1,115 +0,0 @@
import React, { useState } from "react";
import axiosapi from "../api/axiosapi";
import TextField from "@material-ui/core/TextField";
import Typography from "@material-ui/core/Typography";
import CssBaseline from "@material-ui/core/CssBaseline";
import Container from "@material-ui/core/Container";
import Button from "@material-ui/core/Button";
import { makeStyles } from "@material-ui/core/styles";
const useStyles = makeStyles(theme => ({
// Styles for various elements
paper: {
marginTop: theme.spacing(8),
display: "flex",
flexDirection: "column",
alignItems: "center",
},
avatar: {
margin: theme.spacing(1),
backgroundColor: theme.palette.secondary.main,
},
form: {
width: "100%",
marginTop: theme.spacing(1),
},
submit: {
margin: theme.spacing(3, 0, 2),
},
}));
const Signup = () => {
const classes = useStyles();
const [formData, setFormData] = useState({
email: "",
username: "",
password: "",
});
const [error, setError] = useState(null);
const [isSubmitting, setIsSubmitting] = useState(false);
const handleSubmit = async e => {
e.preventDefault();
setIsSubmitting(true);
setError(null);
try {
axiosapi.createUser(formData);
} catch (error) {
console.error("Error creating user:", error);
setError("Registration failed. Please try again."); // Set an error message
} finally {
setIsSubmitting(false);
}
};
const handleChange = e => {
const { name, value } = e.target;
setFormData({ ...formData, [name]: value });
};
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Typography component="h1" variant="h5">
Sign Up
</Typography>
<form className={classes.form} onSubmit={handleSubmit}>
<TextField
variant="outlined"
margin="normal"
type="email"
name="email"
fullWidth
value={formData.email}
onChange={handleChange}
label="Email"
/>
<TextField
variant="outlined"
margin="normal"
type="text"
name="username"
fullWidth
value={formData.username}
onChange={handleChange}
label="Username"
/>
<TextField
variant="outlined"
margin="normal"
type="password"
name="password"
fullWidth
value={formData.password}
onChange={handleChange}
label="Password"
/>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
disabled={isSubmitting}>
{isSubmitting ? "Signing up..." : "Sign Up"}
</Button>
</form>
{error && <Typography color="error">{error}</Typography>}
</div>
</Container>
);
};
export default Signup;

View File

@ -1,7 +1,7 @@
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faGoogle, faGithub } from "@fortawesome/free-brands-svg-icons"; import { faGoogle, faGithub } from "@fortawesome/free-brands-svg-icons";
function Signup() { export function Signup() {
return ( return (
<div className="flex items-center justify-center h-screen"> <div className="flex items-center justify-center h-screen">
<div className="flex flex-col items-center bg-white p-10 rounded-lg shadow-md"> <div className="flex flex-col items-center bg-white p-10 rounded-lg shadow-md">
@ -34,5 +34,3 @@ function Signup() {
</div> </div>
); );
} }
export default Signup;

View File

@ -1,47 +0,0 @@
import React, { useState, useEffect } from "react";
import axiosapi from "../api/AuthenticationApi";
import { Button } from "@mui/material";
import { useNavigate } from "react-router-dom";
function TestAuth() {
let Navigate = useNavigate();
const [message, setMessage] = useState("");
useEffect(() => {
// Fetch the "hello" data from the server when the component mounts
axiosapi
.getGreeting()
.then(res => {
console.log(res.data);
setMessage(res.data.user);
})
.catch(err => {
console.log(err);
setMessage("");
});
}, []);
const logout = () => {
// Log out the user, clear tokens, and navigate to the "/testAuth" route
axiosapi.apiUserLogout();
Navigate("/testAuth");
};
return (
<div>
{message !== "" && (
<div>
<h1 class="text-xl font-bold">Login! Hello!</h1>
<h2>{message}</h2>
<Button variant="contained" onClick={logout}>
Logout
</Button>
</div>
)}
{message === "" && <h1 class="text-xl font-bold">Need to sign in, No authentication found</h1>}
</div>
);
}
export default TestAuth;

View File

@ -1,4 +1,4 @@
import React, { Fragment } from "react"; import { Fragment } from "react";
import ReactDOM from "react-dom/client"; import ReactDOM from "react-dom/client";
import App from "./App"; import App from "./App";
import { GoogleOAuthProvider } from "@react-oauth/google"; import { GoogleOAuthProvider } from "@react-oauth/google";

View File

@ -3,17 +3,14 @@
const defaultTheme = require("tailwindcss/defaultTheme"); const defaultTheme = require("tailwindcss/defaultTheme");
export default { export default {
content: [ content: ["./src/**/*.{js,jsx}", "./node_modules/@tremor/**/*.{js,ts,jsx,tsx}"],
"./src/**/*.{js,jsx}",
"./node_modules/@tremor/**/*.{js,ts,jsx,tsx}",
],
theme: { theme: {
extend: { extend: {
fontFamily: { fontFamily: {
sans: ['"Proxima Nova"', ...defaultTheme.fontFamily.sans], sans: ['"Proxima Nova"', ...defaultTheme.fontFamily.sans],
}, },
colors:{ colors: {
tremor: { tremor: {
brand: { brand: {
faint: "#eff6ff", // blue-50 faint: "#eff6ff", // blue-50
@ -42,10 +39,9 @@ export default {
strong: "#111827", // gray-900 strong: "#111827", // gray-900
inverted: "#ffffff", // white inverted: "#ffffff", // white
}, },
}, },
}, },
boxShadow:{ boxShadow: {
"tremor-input": "0 1px 2px 0 rgb(0 0 0 / 0.05)", "tremor-input": "0 1px 2px 0 rgb(0 0 0 / 0.05)",
"tremor-card": "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)", "tremor-card": "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
"tremor-dropdown": "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)", "tremor-dropdown": "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
@ -92,12 +88,7 @@ export default {
/^(fill-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/, /^(fill-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/,
}, },
], ],
plugins: [ plugins: [require("daisyui"), require("@tailwindcss/typography"), require("@headlessui/tailwindcss")],
require("daisyui"),
require("@tailwindcss/typography"),
require("daisyui"),
require("@headlessui/tailwindcss"),
],
daisyui: { daisyui: {
themes: ["light", "night"], themes: ["light", "night"],
}, },