Refactored register services and enhanced user profile functionality
A new RequestService was introduced to standardize the HTTP requests, and the register service was refactored to use it. Improvements were made to the handling of user profile data along with error handling and display. New components were created for displaying the user profile, and changes to existing components were made to accommodate the service and data handling updates.
This commit is contained in:
parent
e3a5c0a44a
commit
c0327f9607
25
.idea/workspace.xml
generated
25
.idea/workspace.xml
generated
@ -5,8 +5,14 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="42d2b9e8-8d19-46be-8636-69ddba4519e4" name="Changes" comment="">
|
<list default="true" id="42d2b9e8-8d19-46be-8636-69ddba4519e4" name="Changes" comment="">
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/components/profile.tsx" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/services/account.service.ts" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/services/request.service.ts" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/types/userdata.type.ts" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/services/register.service.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/services/register.service.ts" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/app/profile/page.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/profile/page.tsx" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/components/register-form.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/register-form.tsx" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/services/register.service.ts" beforeDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
@ -16,8 +22,8 @@
|
|||||||
<component name="FileTemplateManagerImpl">
|
<component name="FileTemplateManagerImpl">
|
||||||
<option name="RECENT_TEMPLATES">
|
<option name="RECENT_TEMPLATES">
|
||||||
<list>
|
<list>
|
||||||
<option value="TypeScript JSX File" />
|
|
||||||
<option value="TypeScript File" />
|
<option value="TypeScript File" />
|
||||||
|
<option value="TypeScript JSX File" />
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
@ -84,7 +90,7 @@
|
|||||||
<workItem from="1715776267209" duration="3260000" />
|
<workItem from="1715776267209" duration="3260000" />
|
||||||
<workItem from="1715781823049" duration="3317000" />
|
<workItem from="1715781823049" duration="3317000" />
|
||||||
<workItem from="1715794057604" duration="8757000" />
|
<workItem from="1715794057604" duration="8757000" />
|
||||||
<workItem from="1716275453494" duration="15864000" />
|
<workItem from="1716275453494" duration="29883000" />
|
||||||
</task>
|
</task>
|
||||||
<task id="LOCAL-00001" summary="Remove toast components and added register form The toast related components (toast.tsx, toaster.tsx, use-toast.ts) were removed from the code base. On the other hand, the register-form.tsx file was updated with a form for users to create an account. A new file toast-box.tsx was also added to display a custom message box.">
|
<task id="LOCAL-00001" summary="Remove toast components and added register form The toast related components (toast.tsx, toaster.tsx, use-toast.ts) were removed from the code base. On the other hand, the register-form.tsx file was updated with a form for users to create an account. A new file toast-box.tsx was also added to display a custom message box.">
|
||||||
<option name="closed" value="true" />
|
<option name="closed" value="true" />
|
||||||
@ -110,7 +116,15 @@
|
|||||||
<option name="project" value="LOCAL" />
|
<option name="project" value="LOCAL" />
|
||||||
<updated>1716300616160</updated>
|
<updated>1716300616160</updated>
|
||||||
</task>
|
</task>
|
||||||
<option name="localTasksCounter" value="4" />
|
<task id="LOCAL-00004" summary="Refactor register service to enhance error handling Modified the doRegister function within register.service.ts to provide better error handling. Responses now return an object format, and an error catch block has been added. Additionally, minor changes were made to the workspace.xml.">
|
||||||
|
<option name="closed" value="true" />
|
||||||
|
<created>1716301028386</created>
|
||||||
|
<option name="number" value="00004" />
|
||||||
|
<option name="presentableId" value="LOCAL-00004" />
|
||||||
|
<option name="project" value="LOCAL" />
|
||||||
|
<updated>1716301028386</updated>
|
||||||
|
</task>
|
||||||
|
<option name="localTasksCounter" value="5" />
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
<component name="TypeScriptGeneratedFilesManager">
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
@ -120,6 +134,7 @@
|
|||||||
<MESSAGE value="Remove toast components and added register form The toast related components (toast.tsx, toaster.tsx, use-toast.ts) were removed from the code base. On the other hand, the register-form.tsx file was updated with a form for users to create an account. A new file toast-box.tsx was also added to display a custom message box." />
|
<MESSAGE value="Remove toast components and added register form The toast related components (toast.tsx, toaster.tsx, use-toast.ts) were removed from the code base. On the other hand, the register-form.tsx file was updated with a form for users to create an account. A new file toast-box.tsx was also added to display a custom message box." />
|
||||||
<MESSAGE value="Add ProfilePage, update RegisterForm and ToastBox components Added new ProfilePage component with necessary UI layout and buttons. Updated RegisterForm component with form validation using Zod schema and improved error handling. Updated icons in ToastBox component for proper display. Added necessary dependencies for form handling and validation." />
|
<MESSAGE value="Add ProfilePage, update RegisterForm and ToastBox components Added new ProfilePage component with necessary UI layout and buttons. Updated RegisterForm component with form validation using Zod schema and improved error handling. Updated icons in ToastBox component for proper display. Added necessary dependencies for form handling and validation." />
|
||||||
<MESSAGE value="Integrate registration service and axios dependency The registration form now makes use of a new registration service. Axios, a necessary dependency for making HTTP requests in this service, has been added to the project. Additionally, logging has been improved in the user registration process to provide better debugging information." />
|
<MESSAGE value="Integrate registration service and axios dependency The registration form now makes use of a new registration service. Axios, a necessary dependency for making HTTP requests in this service, has been added to the project. Additionally, logging has been improved in the user registration process to provide better debugging information." />
|
||||||
<option name="LAST_COMMIT_MESSAGE" value="Integrate registration service and axios dependency The registration form now makes use of a new registration service. Axios, a necessary dependency for making HTTP requests in this service, has been added to the project. Additionally, logging has been improved in the user registration process to provide better debugging information." />
|
<MESSAGE value="Refactor register service to enhance error handling Modified the doRegister function within register.service.ts to provide better error handling. Responses now return an object format, and an error catch block has been added. Additionally, minor changes were made to the workspace.xml." />
|
||||||
|
<option name="LAST_COMMIT_MESSAGE" value="Refactor register service to enhance error handling Modified the doRegister function within register.service.ts to provide better error handling. Responses now return an object format, and an error catch block has been added. Additionally, minor changes were made to the workspace.xml." />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
@ -1,19 +1,67 @@
|
|||||||
import React from "react";
|
'use client'
|
||||||
|
import React, {useEffect, useState} from "react";
|
||||||
import {Button} from "@/components/ui/button";
|
import {Button} from "@/components/ui/button";
|
||||||
import {KeyRound, Rss, UserRoundPlus} from "lucide-react";
|
import Link from "next/link";
|
||||||
|
import {AccountService} from "@/services/account.service";
|
||||||
|
import {IUserDataProfile} from "@/types/userdata.type";
|
||||||
|
import {TriangleAlert} from "lucide-react";
|
||||||
|
import {Profile} from "@/components/profile";
|
||||||
|
|
||||||
export default function ProfilePage() {
|
export default function ProfilePage() {
|
||||||
|
const token = localStorage.getItem('token') || false
|
||||||
|
if (!token) {
|
||||||
return (
|
return (
|
||||||
<main className="flex flex-col justify-evenly items-center antialiased h-full w-full">
|
<main className="flex flex-col justify-evenly items-center antialiased h-full w-full gap-2">
|
||||||
<section className={"flex flex-col justify-evenly items-center md:h-1/3 mt-4 p-2 w-full h-full gap-1"}>
|
<h1 className={'md:text-xl text-center'}>You should be logged to see the page.</h1>
|
||||||
<h1 className={"text-4xl md:text-6xl font-bold"}>Only<em className={"text-primary opacity-65"}>Devs</em></h1>
|
<div className={'flex flex-row justify-center gap-2 md:scale-125'}>
|
||||||
<h2 className={"text-xl md:text-3xl text-center mt-1"}>A social network for you the <em className={"text-primary opacity-65"}>nerdy</em> developer !</h2>
|
<Button size="default" asChild><Link href={'/account/login'}>Login</Link></Button>
|
||||||
<div className={"flex flex-col md:flex-row justify-evenly max-w-64 w-full md:max-w-full mt-2 gap-1"}>
|
<Button size="default" variant="outline" asChild><Link href={'/account/register'}>Register</Link></Button>
|
||||||
<Button className={"mt-3 md:scale-125 gap-2 bg-purple-600"}><KeyRound />Login</Button>
|
|
||||||
<Button className={"mt-3 md:scale-125 gap-2 bg-purple-800"}><UserRoundPlus />Register</Button>
|
|
||||||
<Button className={"mt-3 md:scale-125 gap-2"}><Rss />Go see the posts</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const [userData, setUserData] = useState<IUserDataProfile>();
|
||||||
|
const [httpError, setHttpError] = useState<string>()
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await AccountService.getUserData();
|
||||||
|
if (typeof response === 'string') {
|
||||||
|
setHttpError(response)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setUserData(response);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (httpError) {
|
||||||
|
return (
|
||||||
|
<main className="flex flex-col justify-evenly items-center antialiased h-full w-full gap-2">
|
||||||
|
<div className={'flex flex-col md:flex-row justify-center items-center gap-2 md:scale-125 text-orange-500 font-bold'}>
|
||||||
|
<TriangleAlert className={
|
||||||
|
'md:scale-150'
|
||||||
|
} />
|
||||||
|
<h1 className={'md:text-xl text-center'}>{`${httpError}`}</h1>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userData?.email) {
|
||||||
|
return (
|
||||||
|
<main className="flex flex-col justify-evenly items-center antialiased h-full w-full">
|
||||||
|
<Profile userData={userData}/>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<main className="flex flex-col justify-evenly items-center antialiased h-full w-full gap-2">
|
||||||
|
<h1 className={'md:text-xl text-center'}>Loading...</h1>
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
26
src/components/profile.tsx
Normal file
26
src/components/profile.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
'use client'
|
||||||
|
import {IUserDataProfile} from "@/types/userdata.type";
|
||||||
|
|
||||||
|
export function Profile({asAdmin, userData}: {asAdmin?: boolean, userData: IUserDataProfile}) {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className={'flex flex-col justify-start items-center w-full min-h-screen'}>
|
||||||
|
<div className={'flew w-full h-24 md:h-32 bg-purple-600'}>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div className={'flex flex-row justify-evenly w-full h-32 bg-purple-700'}>
|
||||||
|
<div className={'flex flex-row gap-2'}>
|
||||||
|
<div className={'w-16 h-16 rounded-full bg-purple-800 justify-center items-center'}>
|
||||||
|
<p>
|
||||||
|
PP
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
Title
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
@ -11,7 +11,7 @@ import toast, {ToastBar} from "react-hot-toast";
|
|||||||
import {ToastBox, toastType} from "@/components/ui/toast-box";
|
import {ToastBox, toastType} from "@/components/ui/toast-box";
|
||||||
import {zodResolver} from "@hookform/resolvers/zod"
|
import {zodResolver} from "@hookform/resolvers/zod"
|
||||||
import {z} from 'zod'
|
import {z} from 'zod'
|
||||||
import doRegister from "@/services/register.service";
|
import {AccountService} from "@/services/account.service";
|
||||||
|
|
||||||
const Schema = z.object({
|
const Schema = z.object({
|
||||||
username:
|
username:
|
||||||
@ -67,7 +67,6 @@ function ErrorLabel({message}: {message: string}) {
|
|||||||
<p className={'text-red-700'}>{message}</p>
|
<p className={'text-red-700'}>{message}</p>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function RegisterForm() {
|
export function RegisterForm() {
|
||||||
@ -84,9 +83,15 @@ export function RegisterForm() {
|
|||||||
|
|
||||||
const onSubmit: SubmitHandler<UserInsert> = async (data) => {
|
const onSubmit: SubmitHandler<UserInsert> = async (data) => {
|
||||||
console.log('ping');
|
console.log('ping');
|
||||||
const result = await doRegister(data)
|
const result = await AccountService.register(data)
|
||||||
console.log(result);
|
console.log(result);
|
||||||
//if (result.status === 'BAD')
|
if (!result.success) {
|
||||||
|
toast.custom(<ToastBox
|
||||||
|
message={result.message}
|
||||||
|
type={toastType.refused}
|
||||||
|
/>)
|
||||||
|
return
|
||||||
|
}
|
||||||
toast.custom(<ToastBox
|
toast.custom(<ToastBox
|
||||||
title={`Verify your email`}
|
title={`Verify your email`}
|
||||||
message={`Please verify you mail inbox to activate your account.`}
|
message={`Please verify you mail inbox to activate your account.`}
|
||||||
|
39
src/services/account.service.ts
Normal file
39
src/services/account.service.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import axios from "axios";
|
||||||
|
import RequestService from "@/services/request.service";
|
||||||
|
import {IUserDataProfile} from "@/types/userdata.type";
|
||||||
|
|
||||||
|
async function doRegister(data: object) {
|
||||||
|
const res = await RequestService.standard.post.json('http://localhost:3333/auth/register', data)
|
||||||
|
console.debug(`Register request get a ${res.status} response.`);
|
||||||
|
if (res.status !== 201) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
message: res.data.message || res.data.error,
|
||||||
|
status: res.status,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
localStorage.removeItem('token')
|
||||||
|
localStorage.setItem('token', res.data.token)
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
message: res.data.message,
|
||||||
|
status: res.status,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getUserData() {
|
||||||
|
const res = await RequestService.authenticated.get.json('http://localhost:3333/auth/me')
|
||||||
|
//TODO Manage error
|
||||||
|
console.log(res);
|
||||||
|
if (res.status !== 302) {
|
||||||
|
return res.data.message as string;
|
||||||
|
}
|
||||||
|
return res.data as IUserDataProfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AccountService = {
|
||||||
|
register: doRegister,
|
||||||
|
getUserData,
|
||||||
|
};
|
@ -1,22 +0,0 @@
|
|||||||
'use client'
|
|
||||||
|
|
||||||
import axios from "axios";
|
|
||||||
|
|
||||||
|
|
||||||
async function doRegister(data: object) {
|
|
||||||
return axios.post('http://localhost:3333/auth/register', data)
|
|
||||||
.then(function (response) {
|
|
||||||
console.log(response);
|
|
||||||
return {
|
|
||||||
status: response.status,
|
|
||||||
data: response.data
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
console.warn(error);
|
|
||||||
return {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export default doRegister;
|
|
71
src/services/request.service.ts
Normal file
71
src/services/request.service.ts
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import axios, {type AxiosResponse} from "axios";
|
||||||
|
|
||||||
|
const AxiosConfigs = {
|
||||||
|
authenticated: {
|
||||||
|
json: () => {
|
||||||
|
return {
|
||||||
|
headers: {
|
||||||
|
'content-type': 'application/json',
|
||||||
|
Authorization: `Bearer ${localStorage.getItem('token')}`,
|
||||||
|
},
|
||||||
|
validateStatus: function (status: number) {
|
||||||
|
return status < 500; // Resolve only if the status code is less than 500
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
standard: {
|
||||||
|
json: () => {
|
||||||
|
return {
|
||||||
|
headers: {
|
||||||
|
'content-type': 'application/json'
|
||||||
|
},
|
||||||
|
validateStatus: function (status: number) {
|
||||||
|
return status < 500; // Resolve only if the status code is less than 500
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function doAuthenticatedJsonPostReq(url:string, body:object): Promise<AxiosResponse<any, any>> {
|
||||||
|
return await axios.post(url, body, AxiosConfigs.authenticated.json())
|
||||||
|
}
|
||||||
|
async function doAuthenticatedGetReq(url: string): Promise<AxiosResponse<any, any>> {
|
||||||
|
return await axios.get(url, AxiosConfigs.authenticated.json())
|
||||||
|
}
|
||||||
|
|
||||||
|
async function doAuthenticatedPatchReq(url: string, body: object): Promise<AxiosResponse<any, any>> {
|
||||||
|
return await axios.patch(url, body, AxiosConfigs.authenticated.json())
|
||||||
|
}
|
||||||
|
|
||||||
|
async function doAuthenticatedDelReq(url: string): Promise<AxiosResponse<any, any>> {
|
||||||
|
return await axios.delete(url, AxiosConfigs.authenticated.json())
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO form/multipart req
|
||||||
|
|
||||||
|
|
||||||
|
async function doJsonPostReq(url:string, body: object): Promise<AxiosResponse<any, any>> {
|
||||||
|
return await axios.post(url, body, AxiosConfigs.standard.json())
|
||||||
|
}
|
||||||
|
async function doJsonGetReq(url: string): Promise<AxiosResponse<any, any>> {
|
||||||
|
return await axios.get(url, AxiosConfigs.standard.json());
|
||||||
|
}
|
||||||
|
|
||||||
|
const RequestService = {
|
||||||
|
authenticated: {
|
||||||
|
post: {json: doAuthenticatedJsonPostReq},
|
||||||
|
patch: {json: doAuthenticatedPatchReq},
|
||||||
|
delete: {json: doAuthenticatedDelReq},
|
||||||
|
get: {json: doAuthenticatedGetReq}
|
||||||
|
},
|
||||||
|
standard: {
|
||||||
|
post: {json: doJsonPostReq},
|
||||||
|
get: {json: doJsonGetReq}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RequestService;
|
16
src/types/userdata.type.ts
Normal file
16
src/types/userdata.type.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
export interface IUserDataProfile {
|
||||||
|
id: string;
|
||||||
|
username: string;
|
||||||
|
email: string;
|
||||||
|
displayName: string;
|
||||||
|
isAdmin: boolean;
|
||||||
|
followers: FollowsAndFollowers[];
|
||||||
|
following: FollowsAndFollowers[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FollowsAndFollowers {
|
||||||
|
id: string,
|
||||||
|
source_id: string,
|
||||||
|
target_id: string,
|
||||||
|
iat?: number
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user