feat(components, services): Add user data management and account handling
This commit introduces user data management with the addition of new interfaces and services. User data interface which defines the structure of user data was created. Account handler service for registering, logging in, updating user data and disconnecting was also added. User data provider component was created for managing user data state. The account info component for displaying and editing the user account was introduced too. Finally, updates were made in the existing components and services for accommodating these new elements.
This commit is contained in:
22
src/components/account-dialog.tsx
Normal file
22
src/components/account-dialog.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
"use client"
|
||||
|
||||
import {useContext} from "react";
|
||||
import {UserDataContext} from "@/components/providers/userdata-provider";
|
||||
import {AccountInfo} from "@/components/account-info";
|
||||
|
||||
|
||||
export function AccountDialog() {
|
||||
const userContext = useContext(UserDataContext)
|
||||
|
||||
if (!userContext?.userData) {
|
||||
userContext?.setUserData({name: "Mathis"})
|
||||
return (<p>Loading...</p>)
|
||||
}
|
||||
|
||||
//TODO No account context
|
||||
|
||||
//TODO Loading context
|
||||
|
||||
//TODO Account context
|
||||
return (<AccountInfo userData={userContext.userData}/>)
|
||||
}
|
||||
58
src/components/account-info.tsx
Normal file
58
src/components/account-info.tsx
Normal file
@@ -0,0 +1,58 @@
|
||||
"use client"
|
||||
|
||||
import {IUserData} from "@/interfaces/userdata.interface";
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { Label } from "@/components/ui/label"
|
||||
import {
|
||||
Sheet,
|
||||
SheetClose,
|
||||
SheetContent,
|
||||
SheetDescription,
|
||||
SheetFooter,
|
||||
SheetHeader,
|
||||
SheetTitle,
|
||||
SheetTrigger,
|
||||
} from "@/components/ui/sheet"
|
||||
import {User} from "lucide-react";
|
||||
|
||||
|
||||
export function AccountInfo({userData}: {userData: IUserData}) {
|
||||
return (
|
||||
<Sheet>
|
||||
<SheetTrigger asChild>
|
||||
<Button variant="outline" className={"gap-1"}>
|
||||
<User />
|
||||
{userData?.name || "?"}
|
||||
</Button>
|
||||
</SheetTrigger>
|
||||
<SheetContent>
|
||||
<SheetHeader>
|
||||
<SheetTitle>Edit profile</SheetTitle>
|
||||
<SheetDescription>
|
||||
Make changes to your profile here. Click save when you're done.
|
||||
</SheetDescription>
|
||||
</SheetHeader>
|
||||
<div className="grid gap-4 py-4">
|
||||
<div className="grid grid-cols-4 items-center gap-4">
|
||||
<Label htmlFor="name" className="text-right">
|
||||
Name
|
||||
</Label>
|
||||
<Input id="name" placeholder={userData.name} className="col-span-3" onChange={(event)=>{console.log(event.target.value)}} />
|
||||
</div>
|
||||
<div className="grid grid-cols-4 items-center gap-4">
|
||||
<Label htmlFor="username" className="text-right">
|
||||
Username
|
||||
</Label>
|
||||
<Input id="username" value="@peduarte" className="col-span-3" />
|
||||
</div>
|
||||
</div>
|
||||
<SheetFooter>
|
||||
<SheetClose asChild>
|
||||
<Button type="submit">Save changes</Button>
|
||||
</SheetClose>
|
||||
</SheetFooter>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
)
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import Image from "next/image";
|
||||
import React from "react";
|
||||
import {ThemeBtnSelector} from "@/components/theme-btn-selector";
|
||||
import {AccountDialog} from "@/components/account-dialog";
|
||||
|
||||
|
||||
export function Header({title, children}: {title?: string, children?: React.ReactNode}) {
|
||||
@@ -16,7 +17,8 @@ export function Header({title, children}: {title?: string, children?: React.Reac
|
||||
<div className={"w-1/3 flex flex-row justify-center items-center"}>
|
||||
{children}
|
||||
</div>
|
||||
<div className={"w-1/3 flex flex-row justify-end items-center"}>
|
||||
<div className={"w-1/3 flex flex-row justify-end gap-2 items-center"}>
|
||||
<AccountDialog/>
|
||||
<ThemeBtnSelector/>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
23
src/components/providers/providers.tsx
Normal file
23
src/components/providers/providers.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
"use client"
|
||||
import React from "react";
|
||||
import {Header} from "@/components/header";
|
||||
import {Footer} from "@/components/footer";
|
||||
import {ThemeProvider} from "@/components/providers/theme-provider";
|
||||
import {UserDataProvider} from "@/components/providers/userdata-provider";
|
||||
|
||||
|
||||
export function Providers({children}: { children: React.ReactNode }) {
|
||||
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
attribute="class"
|
||||
defaultTheme="system"
|
||||
enableSystem
|
||||
>
|
||||
<UserDataProvider>
|
||||
{children}
|
||||
</UserDataProvider>
|
||||
</ThemeProvider>
|
||||
)
|
||||
}
|
||||
21
src/components/providers/userdata-provider.tsx
Normal file
21
src/components/providers/userdata-provider.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import React from 'react';
|
||||
import {IUserData} from "@/interfaces/userdata.interface";
|
||||
import {useEncodedLocalStorage} from "@/services/localStorage";
|
||||
|
||||
export interface IUserDataProvider {
|
||||
userData: IUserData | undefined;
|
||||
setUserData: React.Dispatch<React.SetStateAction<IUserData | undefined>>
|
||||
}
|
||||
|
||||
export const UserDataContext = React.createContext<IUserDataProvider | undefined>(undefined);
|
||||
|
||||
export const UserDataProvider = ({children}: {children: React.ReactNode}) => {
|
||||
const [userData, setUserData] = useEncodedLocalStorage<IUserData | undefined>("user_data", undefined);
|
||||
|
||||
|
||||
return (
|
||||
<UserDataContext.Provider value={{userData, setUserData}}>
|
||||
{children}
|
||||
</UserDataContext.Provider>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user