mirror of
https://github.com/ForFarmTeam/ForFarm.git
synced 2025-12-19 14:04:08 +01:00
feat: use cookie instead of localstorage for token
This commit is contained in:
parent
29c9c4e07a
commit
626ad87d88
@ -2,7 +2,7 @@ import axios from "axios";
|
|||||||
import axiosInstance from "./config";
|
import axiosInstance from "./config";
|
||||||
|
|
||||||
export interface LoginResponse {
|
export interface LoginResponse {
|
||||||
Token: string;
|
token: string;
|
||||||
message?: string;
|
message?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,15 +15,17 @@ import Link from "next/link";
|
|||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { GoogleSigninButton } from "./google-oauth";
|
import { GoogleSigninButton } from "./google-oauth";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { useState } from "react";
|
import { useContext, useState } from "react";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
|
|
||||||
import { loginUser } from "@/api/authentication";
|
import { loginUser } from "@/api/authentication";
|
||||||
|
import { SessionContext } from "@/context/SessionContext";
|
||||||
|
|
||||||
export default function SigninPage() {
|
export default function SigninPage() {
|
||||||
const [serverError, setServerError] = useState<string | null>(null);
|
const [serverError, setServerError] = useState<string | null>(null);
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const session = useContext(SessionContext);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
@ -43,8 +45,13 @@ export default function SigninPage() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const data = await loginUser(values.email, values.password);
|
const data = await loginUser(values.email, values.password);
|
||||||
localStorage.setItem("token", data.Token);
|
|
||||||
localStorage.setItem("user", values.email);
|
if (!data) {
|
||||||
|
setServerError("An error occurred while logging in. Please try again.");
|
||||||
|
throw new Error("No data received from the server.");
|
||||||
|
}
|
||||||
|
session!.setToken(data.token);
|
||||||
|
session!.setUser(values.email);
|
||||||
|
|
||||||
router.push("/setup");
|
router.push("/setup");
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
|
|||||||
@ -5,24 +5,27 @@ import { useForm } from "react-hook-form";
|
|||||||
|
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
import { Checkbox } from "@/components/ui/checkbox";
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
|
||||||
import { signUpSchema } from "@/schema/authSchema";
|
import { signUpSchema } from "@/schema/authSchema";
|
||||||
|
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { useState } from "react";
|
import { useContext, useState } from "react";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
|
|
||||||
import { registerUser } from "@/api/authentication";
|
import { registerUser } from "@/api/authentication";
|
||||||
|
import { SessionContext } from "@/context/SessionContext";
|
||||||
|
|
||||||
export default function SignupPage() {
|
export default function SignupPage() {
|
||||||
const [serverError, setServerError] = useState<string | null>(null);
|
const [serverError, setServerError] = useState<string | null>(null);
|
||||||
const [successMessage, setSuccessMessage] = useState<string | null>(null);
|
const [successMessage, setSuccessMessage] = useState<string | null>(null);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const session = useContext(SessionContext);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
@ -40,20 +43,25 @@ export default function SignupPage() {
|
|||||||
const onSubmit = async (values: z.infer<typeof signUpSchema>) => {
|
const onSubmit = async (values: z.infer<typeof signUpSchema>) => {
|
||||||
setServerError(null);
|
setServerError(null);
|
||||||
setSuccessMessage(null);
|
setSuccessMessage(null);
|
||||||
|
setIsLoading(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const data = await registerUser(values.email, values.password);
|
const data = await registerUser(values.email, values.password);
|
||||||
|
|
||||||
localStorage.setItem("token", data.token);
|
if (!data) {
|
||||||
localStorage.setItem("user", values.email);
|
setServerError("An error occurred while registering. Please try again.");
|
||||||
|
throw new Error("No data received from the server.");
|
||||||
|
}
|
||||||
|
session!.setToken(data.token);
|
||||||
|
session!.setUser(values.email);
|
||||||
|
|
||||||
console.log("Registration successful:", data);
|
|
||||||
setSuccessMessage("Registration successful! You can now sign in.");
|
setSuccessMessage("Registration successful! You can now sign in.");
|
||||||
|
|
||||||
router.push("/setup");
|
router.push("/setup");
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error("Error during registration:", error);
|
console.error("Error during registration:", error);
|
||||||
setServerError(error.message);
|
setServerError(error.message);
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -105,8 +113,8 @@ export default function SignupPage() {
|
|||||||
{serverError && <p className="text-red-600 mt-2 text-sm">{serverError}</p>}
|
{serverError && <p className="text-red-600 mt-2 text-sm">{serverError}</p>}
|
||||||
{successMessage && <p className="text-green-600 mt-2 text-sm">{successMessage}</p>}
|
{successMessage && <p className="text-green-600 mt-2 text-sm">{successMessage}</p>}
|
||||||
|
|
||||||
<Button type="submit" className="mt-5 rounded-full">
|
<Button type="submit" className="mt-5 rounded-full" disabled={isLoading}>
|
||||||
Sign up
|
{isLoading ? "Signing up..." : "Sign up"}
|
||||||
</Button>
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@ -36,7 +36,7 @@ export default function RootLayout({
|
|||||||
<html lang="en" suppressHydrationWarning>
|
<html lang="en" suppressHydrationWarning>
|
||||||
<head />
|
<head />
|
||||||
<SessionProvider>
|
<SessionProvider>
|
||||||
<body className={`${openSans.variable} ${robotoMono.variable} font-sans antialiased`}>
|
<body className={`${openSans.variable} ${robotoMono.variable} antialiased`}>
|
||||||
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
||||||
<div className="relative flex min-h-screen flex-col">
|
<div className="relative flex min-h-screen flex-col">
|
||||||
<div className="flex-1 bg-background">{children}</div>
|
<div className="flex-1 bg-background">{children}</div>
|
||||||
|
|||||||
@ -41,7 +41,7 @@ export default function Home() {
|
|||||||
It's a smart and easy way to optimize your agricultural business, with the help of AI-driven insights and
|
It's a smart and easy way to optimize your agricultural business, with the help of AI-driven insights and
|
||||||
real-time data.
|
real-time data.
|
||||||
</p>
|
</p>
|
||||||
<Link href="/auth/signin">
|
<Link href="/setup">
|
||||||
<Button className="bg-black text-white text-md font-bold px-4 py-6 rounded-full hover:bg-gray-600">
|
<Button className="bg-black text-white text-md font-bold px-4 py-6 rounded-full hover:bg-gray-600">
|
||||||
Manage your farm
|
Manage your farm
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { createContext, useContext, useState, useEffect, ReactNode } from "react";
|
import React, { createContext, useContext, useState, useEffect, ReactNode } from "react";
|
||||||
|
import Cookies from "js-cookie";
|
||||||
|
|
||||||
interface SessionContextType {
|
interface SessionContextType {
|
||||||
token: string | null;
|
token: string | null;
|
||||||
@ -21,17 +22,15 @@ export function SessionProvider({ children }: SessionProviderProps) {
|
|||||||
const [user, setUserState] = useState<any | null>(null);
|
const [user, setUserState] = useState<any | null>(null);
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
|
|
||||||
// Save or remove token from localStorage accordingly
|
|
||||||
const setToken = (newToken: string | null) => {
|
const setToken = (newToken: string | null) => {
|
||||||
if (newToken) {
|
if (newToken) {
|
||||||
localStorage.setItem("token", newToken);
|
Cookies.set("token", newToken, { expires: 7 });
|
||||||
} else {
|
} else {
|
||||||
localStorage.removeItem("token");
|
Cookies.remove("token");
|
||||||
}
|
}
|
||||||
setTokenState(newToken);
|
setTokenState(newToken);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Save or remove user from localStorage accordingly
|
|
||||||
const setUser = (newUser: any | null) => {
|
const setUser = (newUser: any | null) => {
|
||||||
if (newUser) {
|
if (newUser) {
|
||||||
localStorage.setItem("user", JSON.stringify(newUser));
|
localStorage.setItem("user", JSON.stringify(newUser));
|
||||||
@ -41,9 +40,8 @@ export function SessionProvider({ children }: SessionProviderProps) {
|
|||||||
setUserState(newUser);
|
setUserState(newUser);
|
||||||
};
|
};
|
||||||
|
|
||||||
// On mount, check localStorage for token and user data
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const storedToken = localStorage.getItem("token");
|
const storedToken = Cookies.get("token") || null;
|
||||||
const storedUser = localStorage.getItem("user");
|
const storedUser = localStorage.getItem("user");
|
||||||
if (storedToken) {
|
if (storedToken) {
|
||||||
setTokenState(storedToken);
|
setTokenState(storedToken);
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
import { useContext } from "react";
|
import { useContext } from "react";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { SessionContext } from "@/context/SessionContext";
|
import { SessionContext } from "@/context/SessionContext";
|
||||||
|
import Cookies from "js-cookie";
|
||||||
|
|
||||||
export function useLogout() {
|
export function useLogout() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -15,9 +16,13 @@ export function useLogout() {
|
|||||||
const { setToken, setUser } = context;
|
const { setToken, setUser } = context;
|
||||||
|
|
||||||
const logout = () => {
|
const logout = () => {
|
||||||
|
Cookies.remove("token");
|
||||||
|
Cookies.remove("user");
|
||||||
|
|
||||||
setToken(null);
|
setToken(null);
|
||||||
setUser(null);
|
setUser(null);
|
||||||
|
|
||||||
|
console.log(Cookies.get("token"));
|
||||||
router.push("/");
|
router.push("/");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -24,6 +24,7 @@
|
|||||||
"axios": "^1.7.9",
|
"axios": "^1.7.9",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
"js-cookie": "^3.0.5",
|
||||||
"lucide-react": "^0.475.0",
|
"lucide-react": "^0.475.0",
|
||||||
"next": "15.1.0",
|
"next": "15.1.0",
|
||||||
"next-auth": "^4.24.11",
|
"next-auth": "^4.24.11",
|
||||||
|
|||||||
@ -53,6 +53,9 @@ importers:
|
|||||||
clsx:
|
clsx:
|
||||||
specifier: ^2.1.1
|
specifier: ^2.1.1
|
||||||
version: 2.1.1
|
version: 2.1.1
|
||||||
|
js-cookie:
|
||||||
|
specifier: ^3.0.5
|
||||||
|
version: 3.0.5
|
||||||
lucide-react:
|
lucide-react:
|
||||||
specifier: ^0.475.0
|
specifier: ^0.475.0
|
||||||
version: 0.475.0(react@19.0.0)
|
version: 0.475.0(react@19.0.0)
|
||||||
@ -1609,6 +1612,10 @@ packages:
|
|||||||
jose@4.15.9:
|
jose@4.15.9:
|
||||||
resolution: {integrity: sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==}
|
resolution: {integrity: sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==}
|
||||||
|
|
||||||
|
js-cookie@3.0.5:
|
||||||
|
resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==}
|
||||||
|
engines: {node: '>=14'}
|
||||||
|
|
||||||
js-tokens@4.0.0:
|
js-tokens@4.0.0:
|
||||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||||
|
|
||||||
@ -3992,6 +3999,8 @@ snapshots:
|
|||||||
|
|
||||||
jose@4.15.9: {}
|
jose@4.15.9: {}
|
||||||
|
|
||||||
|
js-cookie@3.0.5: {}
|
||||||
|
|
||||||
js-tokens@4.0.0: {}
|
js-tokens@4.0.0: {}
|
||||||
|
|
||||||
js-yaml@4.1.0:
|
js-yaml@4.1.0:
|
||||||
|
|||||||
5
package.json
Normal file
5
package.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"@types/js-cookie": "^3.0.6"
|
||||||
|
}
|
||||||
|
}
|
||||||
22
pnpm-lock.yaml
Normal file
22
pnpm-lock.yaml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
lockfileVersion: '9.0'
|
||||||
|
|
||||||
|
settings:
|
||||||
|
autoInstallPeers: true
|
||||||
|
excludeLinksFromLockfile: false
|
||||||
|
|
||||||
|
importers:
|
||||||
|
|
||||||
|
.:
|
||||||
|
dependencies:
|
||||||
|
'@types/js-cookie':
|
||||||
|
specifier: ^3.0.6
|
||||||
|
version: 3.0.6
|
||||||
|
|
||||||
|
packages:
|
||||||
|
|
||||||
|
'@types/js-cookie@3.0.6':
|
||||||
|
resolution: {integrity: sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==}
|
||||||
|
|
||||||
|
snapshots:
|
||||||
|
|
||||||
|
'@types/js-cookie@3.0.6': {}
|
||||||
Loading…
Reference in New Issue
Block a user