Add profile form

This commit is contained in:
ariari04 2024-09-23 19:35:57 +06:00
parent f7a1bef554
commit e3b73d38c0
4 changed files with 189 additions and 3 deletions

View File

@ -4,12 +4,14 @@ import ProfileAvatar from "@/features/ProfileAvatar/ProfileAvatar";
import { apiInstance } from "@/shared/config/apiConfig"; import { apiInstance } from "@/shared/config/apiConfig";
import { authConfig } from "@/shared/config/authConfig"; import { authConfig } from "@/shared/config/authConfig";
import { IProfile } from "@/shared/types/profile-type"; import { IProfile } from "@/shared/types/profile-type";
import ProfileForm from "@/widgets/forms/ProfileForm/ProfileForm";
import { AxiosError } from "axios"; import { AxiosError } from "axios";
import { getServerSession } from "next-auth"; import { getServerSession } from "next-auth";
import React from "react"; import React from "react";
const Personal = async () => { const Personal = async () => {
const session = await getServerSession(authConfig); const session = await getServerSession(authConfig);
console.log(session?.access_token);
const getProfile = async () => { const getProfile = async () => {
const Authorization = `Bearer ${session?.access_token}`; const Authorization = `Bearer ${session?.access_token}`;
const config = { const config = {
@ -22,7 +24,6 @@ const Personal = async () => {
"/users/profile/", "/users/profile/",
config config
); );
return response.data; return response.data;
} catch (error: unknown) { } catch (error: unknown) {
if (error instanceof AxiosError) console.log(error.message); if (error instanceof AxiosError) console.log(error.message);
@ -33,7 +34,13 @@ const Personal = async () => {
return ( return (
<div className="personal"> <div className="personal">
<ProfileAvatar img={data?.image as string} /> {/* <ProfileAvatar img={data?.image as string} /> */}
<ProfileForm
id={data?.id as number}
first_name={data?.first_name as string}
last_name={data?.last_name as string}
email={data?.email as string}
/>
</div> </div>
); );
}; };

View File

@ -57,7 +57,7 @@ const TenderCard: React.FC<Props> = ({
<div className="w-[290px]"> <div className="w-[290px]">
<p className="text-[14px] leading-6 mb-[6px]">Планируемая сумма</p> <p className="text-[14px] leading-6 mb-[6px]">Планируемая сумма</p>
<Title <Title
text={`${formatNumber(plan_summ_decimal)} сом`} text={formatNumber(plan_summ_decimal)}
className="font-extrabold text-[24px] leading-[38px] mb-4" className="font-extrabold text-[24px] leading-[38px] mb-4"
/> />

View File

@ -0,0 +1,171 @@
"use client";
import Image from "next/image";
import pen from "./icons/pen.svg";
import { useState } from "react";
import { apiInstance } from "@/shared/config/apiConfig";
import { AxiosError } from "axios";
import { useSession } from "next-auth/react";
import { useRouter } from "@/shared/config/navigation";
import Loader from "@/shared/ui/Loader/Loader";
import LogoutButton from "@/features/LogoutButton";
interface IProfileFormProps {
id: number;
email: string;
first_name: string;
last_name: string;
}
const ProfileForm: React.FC<IProfileFormProps> = ({
id,
email,
first_name,
last_name,
}: IProfileFormProps) => {
const session = useSession();
const router = useRouter();
const [error, setError] = useState<string>("");
const [loader, setLoader] = useState<boolean>(false);
const [editFirstName, setEditFirstName] = useState<boolean>(true);
const [editLastName, setEditLastName] = useState<boolean>(true);
const [firstName, setFirstName] = useState<string>(first_name);
const [lastName, setLastName] = useState<string>(last_name);
const [openPopup, setOpenPopup] = useState<boolean>(false);
const thereAreChanges = () => {
if (firstName !== first_name || lastName !== last_name) return false;
return true;
};
const updateProfile: React.MouseEventHandler<HTMLFormElement> = async (e) => {
e.preventDefault();
const data = {
first_name: firstName,
last_name: lastName,
};
const Authorization = `Bearer ${session.data?.access_token}`;
const config = {
headers: {
Authorization,
},
};
try {
setLoader(true);
const res = await apiInstance.patch(
"/users/profile/update/",
data,
config
);
if ([200, 201].includes(res.status)) {
router.refresh();
}
} catch (error: unknown) {
if (error instanceof AxiosError) {
if (error.response?.status === 400) {
setError("Были введены неккоректные данные");
} else {
setError("Ошибка на стороне сервера");
}
} else {
setError("Возникла непредвиденная ошибка");
}
} finally {
setLoader(false);
}
};
return (
<>
<form onSubmit={updateProfile} className="flex flex-col gap-[25px]">
<div className="flex flex-col gap-[10px]">
<label className="text-[18px] leading-6 text-gray-500">Имя</label>
<div className="flex items-center gap-4">
<input
value={firstName}
onChange={(e) => setFirstName(e.target.value)}
disabled={editFirstName}
type="text"
className="w-full max-w-[957px] p-4 border border-white rounded-sm text-[18px] leading-6 text-black"
/>
<button
type="button"
onClick={() => setEditFirstName((prev) => !prev)}
>
<Image className="w-[22px] h-[22px]" src={pen} alt="Pen Icon" />
</button>
</div>
</div>
<div className="flex flex-col gap-[10px]">
<label className="text-[18px] leading-6 text-gray-500">Фамилия</label>
<div className="flex items-center gap-4">
<input
value={lastName}
onChange={(e) => setLastName(e.target.value)}
disabled={editLastName}
type="text"
className="w-full max-w-[957px] p-4 border border-white rounded-sm text-[18px] leading-6 text-black"
/>
<button
type="button"
onClick={() => setEditLastName((prev) => !prev)}
>
<Image src={pen} alt="Pen Icon" className="w-[22px] h-[22px]" />
</button>
</div>
</div>
<div className="flex flex-col gap-[10px]">
<label className="text-[18px] leading-6 text-gray-500">Email</label>
<div className="flex items-center gap-4">
<input
value={email}
disabled
type="text"
className="w-full max-w-[957px] p-4 border border-white rounded-sm text-[18px] leading-6 text-black"
/>
</div>
</div>
<div className="flex flex-col gap-[10px]">
<label className="text-[18px] leading-6 text-gray-500">Пароль</label>
<div className="flex items-center gap-4">
<input
value={"*****************************"}
disabled={editLastName}
type="password"
className="w-full max-w-[957px] p-4 border border-white rounded-sm text-[18px] leading-6 text-black"
/>
<button onClick={() => setOpenPopup(true)} type="button">
<Image src={pen} alt="Pen Icon" className="w-[22px] h-[22px]" />
</button>
</div>
</div>
{/* {openPopup && <ChangePassword closeWindow={setOpenPopup} />} */}
{error ? <p>{error}</p> : null}
<button
disabled={thereAreChanges()}
type="submit"
className={`mt-[50px] w-fit p-[10px] rounded-sm bg-gray-400 cursor-auto font-bold leading-7 text-gray-200${
thereAreChanges() ? "" : "bg-light-blue cursor-pointer"
}`}
>
{loader ? <Loader /> : "Сохранить изменения"}
</button>
<LogoutButton className="sm:block " />
</form>
</>
);
};
export default ProfileForm;

View File

@ -0,0 +1,8 @@
<svg width="21.908203" height="22.000000" viewBox="0 0 21.9082 22" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<desc>
Created with Pixso.
</desc>
<defs/>
<path id="Vector (Stroke)" d="M14.7539 1.22754C16.3906 -0.40918 19.041 -0.40918 20.6777 1.22754C22.3145 2.86426 22.3145 5.51562 20.6777 7.15234L8.5918 19.2383C8.45508 19.375 8.28516 19.4707 8.09766 19.5166L4.51562 20.3867C4.47852 20.3984 4.44141 20.4072 4.4043 20.4141L2.23047 20.9424C1.875 21.0293 1.5 20.9238 1.24023 20.665C0.982422 20.4062 0.876953 20.0312 0.962891 19.6758L2.38867 13.8076C2.43555 13.6211 2.53125 13.4502 2.66797 13.3145L14.7539 1.22754ZM4.53711 18.2236L7.31641 17.5479L19.1953 5.66895C20.0117 4.85156 20.0117 3.52832 19.1953 2.71094C18.377 1.89355 17.0547 1.89355 16.2363 2.71094L4.35742 14.5889L3.68359 17.3652L4.53711 18.2236Z" fill="#B2B5BE" fill-opacity="1.000000" fill-rule="evenodd"/>
<path id="Union" d="M14.5332 4.09473C14.9434 3.68652 15.6074 3.6875 16.0176 4.09766L19.123 7.21191C19.5312 7.62207 19.5312 8.28613 19.1211 8.69531C18.7109 9.10449 18.0469 9.10352 17.6367 8.69336L14.5312 5.57812C14.123 5.16797 14.123 4.50391 14.5332 4.09473ZM8.77734 19.9238C8.77734 19.3447 9.24609 18.875 9.82617 18.875L20.8594 18.875C21.4375 18.875 21.9082 19.3447 21.9082 19.9238C21.9082 20.5029 21.4375 20.9727 20.8594 20.9727L9.82617 20.9727C9.24609 20.9727 8.77734 20.5029 8.77734 19.9238Z" fill="#B2B5BE" fill-opacity="1.000000" fill-rule="evenodd"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB