Add profile form
This commit is contained in:
parent
f7a1bef554
commit
e3b73d38c0
@ -4,12 +4,14 @@ import ProfileAvatar from "@/features/ProfileAvatar/ProfileAvatar";
|
||||
import { apiInstance } from "@/shared/config/apiConfig";
|
||||
import { authConfig } from "@/shared/config/authConfig";
|
||||
import { IProfile } from "@/shared/types/profile-type";
|
||||
import ProfileForm from "@/widgets/forms/ProfileForm/ProfileForm";
|
||||
import { AxiosError } from "axios";
|
||||
import { getServerSession } from "next-auth";
|
||||
import React from "react";
|
||||
|
||||
const Personal = async () => {
|
||||
const session = await getServerSession(authConfig);
|
||||
console.log(session?.access_token);
|
||||
const getProfile = async () => {
|
||||
const Authorization = `Bearer ${session?.access_token}`;
|
||||
const config = {
|
||||
@ -22,7 +24,6 @@ const Personal = async () => {
|
||||
"/users/profile/",
|
||||
config
|
||||
);
|
||||
|
||||
return response.data;
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof AxiosError) console.log(error.message);
|
||||
@ -33,7 +34,13 @@ const Personal = async () => {
|
||||
|
||||
return (
|
||||
<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>
|
||||
);
|
||||
};
|
||||
|
@ -57,7 +57,7 @@ const TenderCard: React.FC<Props> = ({
|
||||
<div className="w-[290px]">
|
||||
<p className="text-[14px] leading-6 mb-[6px]">Планируемая сумма</p>
|
||||
<Title
|
||||
text={`${formatNumber(plan_summ_decimal)} сом`}
|
||||
text={formatNumber(plan_summ_decimal)}
|
||||
className="font-extrabold text-[24px] leading-[38px] mb-4"
|
||||
/>
|
||||
|
||||
|
171
src/widgets/forms/ProfileForm/ProfileForm.tsx
Normal file
171
src/widgets/forms/ProfileForm/ProfileForm.tsx
Normal 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;
|
8
src/widgets/forms/ProfileForm/icons/pen.svg
Normal file
8
src/widgets/forms/ProfileForm/icons/pen.svg
Normal 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 |
Loading…
Reference in New Issue
Block a user