Files
anti-hvost/src/pages/profile_settings.tsx

110 lines
3.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import Button from "@/components/ui/Button";
import { withTitle } from "@/constructors/Component";
import { UrlsTitle } from "@/enums/urls";
import { useAppContext } from "@/providers/AuthProvider";
import apiClient from "@/services/api";
import { cn } from "@/utils/class-merge";
import { ArrowRightStartOnRectangleIcon, Cog8ToothIcon } from "@heroicons/react/24/outline";
import { FunctionComponent } from "preact";
import { useLocation } from "preact-iso";
import { useEffect, useState } from "preact/hooks";
import classes from "./profile_settings.module.scss";
interface UserProfile {
username: string;
email: string;
status: string;
avatar_url: string | null;
telegram_notifications: boolean;
telegram_chat_id: string;
}
interface UserSettings {
profile: UserProfile;
}
const ProfileSettings: FunctionComponent = () => {
const { isLoggedIn } = useAppContext();
const { route } = useLocation();
const [userData, setUserData] = useState<UserProfile>({
username: "",
email: "",
status: "",
avatar_url: null,
telegram_notifications: false,
telegram_chat_id: "",
});
const maxStatus = 100;
useEffect(() => {
const fetchUserData = async () => {
try {
const response = await apiClient<UserSettings>("/api/settings/view_settings/", { method: "GET" }, isLoggedIn);
setUserData(response.profile);
} catch (error) {
console.error("Failed to fetch user data:", error);
}
};
if (isLoggedIn.value) {
fetchUserData();
}
}, [isLoggedIn.value]);
const handleLogout = async () => {
try {
await apiClient("/api/settings/logout/", { method: "POST", needsCsrf: true }, isLoggedIn);
isLoggedIn.value = false;
localStorage.removeItem("loggedIn");
localStorage.removeItem("user");
route("/login", true);
} catch (error) {
console.error("Logout failed:", error);
}
};
return (
<div class={classes.container}>
<div class="flex w-full flex-col items-center rounded-[4rem] bg-[linear-gradient(180.00deg,rgb(251,194,199),rgba(206,232,251,0.72)_100%)] px-7 py-5 shadow-[0px_4px_4px_0px_rgba(0,0,0,0.25)] md:flex-row">
<div id={classes.avatar}>
{userData.avatar_url ? (
<img src={userData.avatar_url} alt="User avatar" class="h-full w-full rounded-full object-cover" />
) : (
"Аватар"
)}
</div>
<div class={classes.header_block__name}>
<p class="text-4xl font-semibold">{userData.username}</p>
<p class="text-2xl font-light">{userData.status}</p>
<div class="h-1.5 w-full overflow-hidden rounded-2xl bg-white">
<div
class={cn("relative top-0 left-0 h-2 bg-black")}
style={{ width: `${userData.telegram_chat_id ? 100 : 0}%` }}
></div>
</div>
<div class="-mt-3 self-end text-sm font-light">
{userData.telegram_chat_id ? "100" : "0"}/{maxStatus}
</div>
</div>
</div>
<div class={classes.profile_container}>
<div class={classes.settings_block}>
<div class={classes.settings_block__buttons}>
<Button className="flex flex-row items-center justify-center gap-2">
<Cog8ToothIcon class="size-8" /> Настройки
</Button>
<Button
className="flex flex-row items-center justify-center gap-2 bg-[linear-gradient(180.00deg,rgba(246,255,211,0.7),rgba(195,229,253,0.7)_100%)]"
onClick={handleLogout}
>
<ArrowRightStartOnRectangleIcon class="size-8" /> Выйти
</Button>
</div>
</div>
</div>
</div>
);
};
export default withTitle(UrlsTitle.PROFILE, ProfileSettings);