feat: profile settings

This commit is contained in:
2025-05-10 14:20:10 +03:00
parent e342da34c0
commit b5c67c6173
3 changed files with 224 additions and 26 deletions

View File

@@ -1,3 +1,4 @@
import ModalSettings from "@/components/ModalSettings";
import Button from "@/components/ui/Button";
import { withTitle } from "@/constructors/Component";
import { UrlsTitle } from "@/enums/urls";
@@ -12,11 +13,11 @@ 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;
telegram_chat_id: string | null;
current_xp: string;
xp_for_next_status: string;
}
interface UserSettings {
@@ -28,24 +29,23 @@ const ProfileSettings: FunctionComponent = () => {
const { route } = useLocation();
const [userData, setUserData] = useState<UserProfile>({
username: "",
email: "",
status: "",
avatar_url: null,
current_xp: "",
xp_for_next_status: "",
telegram_notifications: false,
telegram_chat_id: "",
});
const maxStatus = 100;
const [isSettingsOpen, setIsSettingsOpen] = useState(false);
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);
}
};
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();
}
@@ -62,35 +62,29 @@ const ProfileSettings: FunctionComponent = () => {
console.error("Logout failed:", error);
}
};
return (
<div class={classes.container}>
<ModalSettings isOpen={isSettingsOpen} setIsOpen={setIsSettingsOpen} onClose={fetchUserData} />
<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 id={classes.avatar}>"Аватар"</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}%` }}
style={{ width: `${(+userData.current_xp / +userData.xp_for_next_status) * 100}%` }}
></div>
</div>
<div class="-mt-3 self-end text-sm font-light">
{userData.telegram_chat_id ? "100" : "0"}/{maxStatus}
{userData.current_xp}/{userData.xp_for_next_status}
</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">
<Button className="flex flex-row items-center justify-center gap-2" onClick={() => setIsSettingsOpen(true)}>
<Cog8ToothIcon class="size-8" /> Настройки
</Button>
<Button