fix: login and logout updates

Signed-off-by: Varun Raj <mailme@varunraj.in>
This commit is contained in:
Varun Raj committed 2024-09-04 19:00:38 +05:30
1 parent 025fce634b
commit 30526e8e46
5 files changed
+93 -88

No files matched your search

+60 -48
View File
@@ -13,11 +13,18 @@ import { Label } from "@/components/ui/label"
import { useState } from "react"
import { loginUser } from "@/handlers/api/user.handler"
import { useConfig } from "@/contexts/ConfigContext"
import { IUser } from "@/types/user"
import Head from "next/head"
export const description =
"A login form with email and password. There's an option to login with Google and a link to sign up if you don't have an account."
export function LoginForm() {
interface ILoginFormProps {
onLogin: (user: IUser) => void
}
export function LoginForm(
{ onLogin }: ILoginFormProps
) {
const { exImmichUrl } = useConfig()
const [formData, setFormData] = useState({
email: "",
@@ -34,9 +41,9 @@ export function LoginForm() {
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
setLoading(true)
loginUser(formData.email, formData.password).then((user) => {
console.log(user)
}).catch((error) => {
loginUser(formData.email, formData.password)
.then(onLogin)
.catch((error) => {
setErrorMessage(error.message)
}).finally(() => {
setLoading(false)
@@ -45,49 +52,54 @@ export function LoginForm() {
return (
<div className="relative flex min-h-screen justify-center flex-col bg-background">
<Card className="mx-auto max-w-sm">
<CardHeader>
<img
src="/favicon.png"
width={32}
height={32}
alt="Immich Power Tools"
className="w-8 h-8"
/>
<CardTitle className="text-2xl">Login to Immich</CardTitle>
<CardDescription>
Login to your connected Immich instance <Link href={exImmichUrl} className="text-xs" target="_blank">({exImmichUrl})</Link>
</CardDescription>
</CardHeader>
<CardContent>
<form className="grid gap-4" onSubmit={handleSubmit}>
<div className="grid gap-2">
<Label htmlFor="email">Email</Label>
<Input
id="email"
type="email"
placeholder="m@example.com"
required
onChange={handleChange}
/>
</div>
<div className="grid gap-2">
<Label htmlFor="password">Password</Label>
<Input id="password" type="password" required
onChange={handleChange}
/>
</div>
<Button type="submit" className="w-full" disabled={loading}>
Login
</Button>
<Button variant="outline" className="w-full" disabled={loading}>
Login with OAuth
</Button>
</form>
</CardContent>
</Card>
</div>
<>
<Head>
<title>Immich Power Tools - Login</title>
</Head>
<div className="relative flex min-h-screen justify-center flex-col bg-background">
<Card className="mx-auto max-w-sm">
<CardHeader>
<img
src="/favicon.png"
width={32}
height={32}
alt="Immich Power Tools"
className="w-8 h-8"
/>
<CardTitle className="text-2xl">Login to Immich</CardTitle>
<CardDescription>
Login to your connected Immich instance <Link href={exImmichUrl} className="text-xs" target="_blank">({exImmichUrl})</Link>
</CardDescription>
</CardHeader>
<CardContent>
<form className="grid gap-4" onSubmit={handleSubmit}>
<div className="grid gap-2">
<Label htmlFor="email">Email</Label>
<Input
id="email"
type="email"
placeholder="m@example.com"
required
onChange={handleChange}
/>
</div>
<div className="grid gap-2">
<Label htmlFor="password">Password</Label>
<Input id="password" type="password" required
onChange={handleChange}
/>
</div>
<Button type="submit" className="w-full" disabled={loading}>
Login
</Button>
<Button variant="outline" className="w-full" disabled={loading}>
Login with OAuth
</Button>
</form>
</CardContent>
</Card>
</div>
</>
)
}
+9 -3
View File
@@ -32,13 +32,16 @@ export default function RootLayout({ children }: RootLayoutProps) {
.finally(() => setLoading(false));
};
const handleLoginCompletion = (user: IUser) => {
setUser(user);
}
useEffect(() => {
fetchData();
}, []);
if (loading) return <Loader />;
if (errorMessage)
return (
<div className="min-h-screen flex flex-col justify-center">
<ErrorBlock
@@ -61,10 +64,13 @@ export default function RootLayout({ children }: RootLayoutProps) {
</div>
);
if (!user) return <LoginForm />;
if (!user) return <LoginForm onLogin={handleLoginCompletion} />;
return (
<UserContext.Provider value={user}>
<UserContext.Provider value={{
...user,
updateContext: setUser,
}}>
<div className="grid max-h-screen min-h-screen w-full md:grid-cols-[200px_1fr] lg:grid-cols-[240px_1fr]">
<Sidebar />
<div className="flex flex-col">{children}</div>
+21 -35
View File
@@ -1,44 +1,26 @@
import { getMe } from "@/handlers/api/user.handler";
import { IUser } from "@/types/user";
import React, { useEffect, useState } from "react";
import React from "react";
import { Button } from "@/components/ui/button"
import Link from "next/link";
import { useConfig } from "@/contexts/ConfigContext";
import { logoutUser } from "@/handlers/api/user.handler"
import { useRouter } from 'next/router';
import { useCurrentUser } from "@/contexts/CurrentUserContext";
import { useToast } from "../ui/use-toast";
export default function ProfileInfo() {
const router = useRouter();
const { immichURL,exImmichUrl } = useConfig();
const [user, setUser] = React.useState<IUser | null>(null);
const [loading, setLoading] = React.useState(true);
const [errorMessage, setErrorMessage] = useState<string | null>(null);
const { updateContext, ...user } = useCurrentUser()
const { immichURL, exImmichUrl } = useConfig();
const toast = useToast();
const fetchData = () => {
return getMe()
.then(setUser)
.catch((error) => {
setErrorMessage(error.message);
})
.finally(() => setLoading(false));
};
const handleLogout = () => {
logoutUser().then((status) => {
console.log(status)
router.push('/login');
const handleLogout = () => logoutUser()
.then(() => {
updateContext(null)
}).catch((error) => {
setErrorMessage(error.message)
toast.toast({
title: "Error",
description: error.message,
})
})
}
useEffect(() => {
fetchData();
}, []);
if (loading) return <div>Loading...</div>;
if (errorMessage) return <div>{errorMessage}</div>;
return (
<>
@@ -51,10 +33,14 @@ export default function ProfileInfo() {
<Link href={immichURL} target="_blank" className="font-mono">
{immichURL}
</Link>
<p className="text-sm">{user?.name}</p>
<Button variant="destructive" className="mx-4" onClick={handleLogout}>
Log Out
</Button>
{user && (
<>
<p className="text-sm">{user?.name}</p>
<Button variant="destructive" className="mx-4" onClick={handleLogout}>
Log Out
</Button>
</>
)}
</div>
<div className="border text-muted-foreground text-xs text-center py-2">
<p>
-1
View File
@@ -53,7 +53,6 @@ export default function Sidebar() {
</div>
<div>
<ProfileInfo />
</div>
</div>
</div>
+3 -1
View File
@@ -1,7 +1,9 @@
import { IUser } from "@/types/user";
import { createContext, useContext } from "react";
interface IUserContextType extends IUser {}
interface IUserContextType extends IUser {
updateContext: (user: IUser | null) => void;
}
const UserContext = createContext<IUserContextType | null>(null);