Profile page barebones

This commit is contained in:
Max 2025-02-02 14:33:49 +03:00
parent b3a0ca7c7a
commit f99e39c712
10 changed files with 204 additions and 30 deletions

View File

@ -1,12 +1,9 @@
import { import { LaptopIcon, PersonIcon } from "@radix-ui/react-icons";
LaptopIcon,
PersonIcon
} from "@radix-ui/react-icons";
import { DropdownMenu, Flex, IconButton, Text } from "@radix-ui/themes"; import { DropdownMenu, Flex, IconButton, Text } from "@radix-ui/themes";
import { Icon } from "@radix-ui/themes/dist/esm/components/callout.js"; import { Icon } from "@radix-ui/themes/dist/esm/components/callout.js";
import { useAtomValue } from "jotai"; import { useAtomValue } from "jotai";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { userAtom } from "../../../../AtomStore/AtomStore"; import { userAtom } from "../../../../AtomStore/AtomStore";
import LoginButton from "./LoginButton/LoginButton"; import LoginButton from "./LoginButton/LoginButton";
import LogoutButton from "./LogoutButton/LogoutButton"; import LogoutButton from "./LogoutButton/LogoutButton";
@ -15,6 +12,8 @@ export default function UserButton() {
const user = useAtomValue(userAtom); const user = useAtomValue(userAtom);
const { t } = useTranslation(); const { t } = useTranslation();
const navigate = useNavigate();
return ( return (
<div className=""> <div className="">
<DropdownMenu.Root> <DropdownMenu.Root>
@ -25,37 +24,33 @@ export default function UserButton() {
</DropdownMenu.Trigger> </DropdownMenu.Trigger>
<DropdownMenu.Content className="w-fit"> <DropdownMenu.Content className="w-fit">
<DropdownMenu.Item> <DropdownMenu.Item onClick={() => navigate("/profile")}>
<Link to={"/user/:user-id/profile"}> <div>
<Flex className="justify-between gap-2"> <Flex className="justify-between w-full gap-2">
<Icon> <Icon>
<PersonIcon /> <PersonIcon />
</Icon> </Icon>
<Text>{t("profile")}</Text> <Text>{t("profile")}</Text>
</Flex> </Flex>
</Link> </div>
</DropdownMenu.Item> </DropdownMenu.Item>
<DropdownMenu.Item> <DropdownMenu.Item onClick={() => navigate("/user/blogs")}>
<Link to={"/user/blogs"}> <div>
<Flex className="justify-between gap-2"> <Flex className="justify-between gap-2">
<Icon> <Icon>
<LaptopIcon /> <LaptopIcon />
</Icon> </Icon>
<Text>{t("yourBlogs")}</Text> <Text>{t("yourBlogs")}</Text>
</Flex> </Flex>
</Link> </div>
</DropdownMenu.Item> </DropdownMenu.Item>
<DropdownMenu.Separator /> <DropdownMenu.Separator />
<DropdownMenu.Item color={user ? "red" : "green"}> <DropdownMenu.Item color={user ? "red" : "green"}>
{user ? ( {user ? <LogoutButton /> : <LoginButton />}
<LogoutButton />
) : (
<LoginButton />
)}
</DropdownMenu.Item> </DropdownMenu.Item>
</DropdownMenu.Content> </DropdownMenu.Content>
</DropdownMenu.Root> </DropdownMenu.Root>

View File

@ -0,0 +1,123 @@
import {
BoxIcon,
FileTextIcon,
LockClosedIcon,
PersonIcon
} from "@radix-ui/react-icons";
import {
Avatar,
Badge,
Box,
Button,
Card,
Flex,
Separator,
TabNav,
Text,
} from "@radix-ui/themes";
import { useLocation, useNavigate } from "react-router-dom";
export default function ProfileNavbar() {
const { hash, pathname } = useLocation();
const navigate = useNavigate();
console.log(`pathname: ${pathname}, hash: ${hash}`);
return (
<>
<Flex className="relative flex flex-col sm:hidden">
<TabNav.Root size={"2"}>
<TabNav.Link
active={pathname === "/profile"}
onClick={() => navigate("/profile")}
>
<Flex className="items-center gap-1">
<Text>About</Text>
</Flex>
</TabNav.Link>
<TabNav.Link
active={pathname === "/profile/sec"}
onClick={() => navigate("/profile/sec")}
>
<Flex className="items-center gap-1">
<Text>Security</Text>
</Flex>
</TabNav.Link>
<TabNav.Link
active={pathname === "/profile/posts"}
onClick={() => navigate("/profile/posts")}
>
<Flex className="items-center gap-1">
<Text>Posts</Text>
{/* <CaretDownIcon /> */}
</Flex>
</TabNav.Link>
</TabNav.Root>
</Flex>
<Flex
direction={"column"}
gap={"4"}
className="absolute shrink collapse sm:relative sm:visible"
>
<Card>
<Flex gap={"2"} direction={"column"}>
<Flex direction={"row"} gap={"2"} align={"baseline"}>
<Avatar fallback="TU" radius="full" />
<Text>Test User</Text>
</Flex>
<Separator size={"4"} />
<Flex gap={"2"}>
<Badge>test</Badge>
<Badge color="amber">user</Badge>
</Flex>
</Flex>
</Card>
<Box className="mx-1">
<Separator
orientation={"horizontal"}
size={"4"}
className=""
/>
</Box>
<Flex gap={"2"} direction={"column"}>
<Button
className="relative"
variant={pathname === "/profile" ? "solid" : "outline"}
onClick={() => navigate("/profile")}
>
<PersonIcon className="absolute left-4" />
<Text>About</Text>
</Button>
<Button
variant={pathname === "/profile/sec" ? "solid" : "outline"}
className="relative"
onClick={() => navigate("/profile/sec")}
>
<LockClosedIcon className="absolute left-4" />
<Text>Security</Text>
</Button>
<Button
variant={pathname === "/profile/posts" ? "solid" : "outline"}
className="relative"
onClick={() => navigate("/profile/posts")}
>
<FileTextIcon className="absolute left-4" />
<Text>Posts</Text>
</Button>
<Button variant="outline" className="relative">
<BoxIcon className="absolute left-4" />
<Text className="max-w-[60%]" truncate>
Work in progress..qwflkqwhfkjqwhfkj.
</Text>
</Button>
</Flex>
</Flex>
</>
);
}

View File

@ -63,7 +63,7 @@ export default function LoginPage() {
return ( return (
<Card <Card
size={"2"} size={"2"}
className="absolute w-1/4 className="absolute w-[25rem] min-w-[20rem]
left-[50%] top-[50%] left-[50%] top-[50%]
translate-x-[-50%] translate-y-[-50%]" translate-x-[-50%] translate-y-[-50%]"
> >

View File

@ -7,10 +7,6 @@ import BlogCreationDialog from "../../Components/Dialogs/BlogCreationDialog/Blog
import { JSONWithInt64 } from "../../utils/idnex"; import { JSONWithInt64 } from "../../utils/idnex";
import SkeletonBoxes from "./SkeletonBoxes/SkeletonBoxes"; import SkeletonBoxes from "./SkeletonBoxes/SkeletonBoxes";
const TAGS = Array.from({ length: 50 }).map(
(_, i, a) => `v1.2.0-beta.${a.length - i}`
);
export default function UserBlogsPage() { export default function UserBlogsPage() {
const { data, isPending, isFetching } = useQuery({ const { data, isPending, isFetching } = useQuery({
queryKey: ["userBlogs"], queryKey: ["userBlogs"],
@ -52,16 +48,14 @@ export default function UserBlogsPage() {
<ScrollArea.Viewport className="size-full"> <ScrollArea.Viewport className="size-full">
<Flex direction={"column"} gap={"2"}> <Flex direction={"column"} gap={"2"}>
{data {data
? data?.map((blog: any, b) => { ? data?.map((blog: any, b: number) => {
return ( return (
<>
<BlogBox <BlogBox
key={b} key={b}
title={blog.title} title={blog.title}
blogId={blog.blog_id} blogId={blog.blog_id}
userId={blog.user_id} userId={blog.user_id}
/> />
</>
); );
}) })
: null} : null}

View File

@ -0,0 +1,8 @@
export default function UserPostsPage() {
return (
<div>
<h1>User Posts Page</h1>
</div>
)
}

View File

@ -0,0 +1,11 @@
import { Box, Flex, Text } from "@radix-ui/themes";
export default function UserProfilePage() {
return (
<Flex direction={"column"} className="flex-grow-[8]">
<Box className="flex-grow-[1]">
<Text>This is user profile</Text>
</Box>
</Flex>
);
}

View File

@ -0,0 +1,8 @@
export default function UserSecurityPage() {
return (
<div>
<h1>User Security Page</h1>
</div>
)
}

View File

@ -12,10 +12,6 @@ const RETRY_INTERVAL_IN_SECONDS = 1;
const SECONDS_IN_MINUTE = 60; const SECONDS_IN_MINUTE = 60;
const MILLS_IN_SECOND = 1000; const MILLS_IN_SECOND = 1000;
const TAGS = Array.from({ length: 50 }).map(
(_, i, a) => `v1.2.0-beta.${a.length - i}`
);
export default function MainPage() { export default function MainPage() {
const setUserData = useSetAtom(userAtom); const setUserData = useSetAtom(userAtom);
@ -65,7 +61,10 @@ export default function MainPage() {
<Box flexGrow={"1"} className="flex-[1]"> <Box flexGrow={"1"} className="flex-[1]">
<NavBar /> <NavBar />
</Box> </Box>
<Box flexGrow={"100"} className="flex overflow-hidden flex-"> <Box
flexGrow={"100"}
className="flex flex-col overflow-hidden"
>
<Outlet /> <Outlet />
</Box> </Box>
</Flex> </Flex>

View File

@ -0,0 +1,17 @@
import { Box, Flex, Separator } from "@radix-ui/themes";
import { Outlet } from "react-router-dom";
import ProfileNavbar from "../../Components/ProfileNavbar/ProfileNavbar";
export default function ProfilePage() {
return (
<Flex className="relative flex-col flex-1 gap-0 mx-4 sm:flex-row sm:gap-4 md:mx-32 lg:mx-60">
<ProfileNavbar />
<Box className="my-2 collapse sm:visible">
<Separator orientation="vertical" size={"4"} />
</Box>
<Outlet />
</Flex>
);
}

View File

@ -7,6 +7,7 @@ import {
} from "react-router-dom"; } from "react-router-dom";
import ArticleViewer from "../Components/ArticleViewer/ArticleViewer"; import ArticleViewer from "../Components/ArticleViewer/ArticleViewer";
import MainPage from "../layout/MainPage/MainPage"; import MainPage from "../layout/MainPage/MainPage";
import ProfilePage from "../layout/ProfilePage/ProfilePage";
import AuthPageWrapper from "../Pages/AuthPageWrapper/AuthPageWrapper"; import AuthPageWrapper from "../Pages/AuthPageWrapper/AuthPageWrapper";
import BlogPage from "../Pages/BlogPage/BlogPage"; import BlogPage from "../Pages/BlogPage/BlogPage";
import LoginPage from "../Pages/LoginRegisterPage/LoginPage/LoginPage"; import LoginPage from "../Pages/LoginRegisterPage/LoginPage/LoginPage";
@ -15,6 +16,9 @@ import RegisterPage from "../Pages/LoginRegisterPage/RegisterPage/RegisterPage";
import PostCreatorPage from "../Pages/PostCreatorPage/PostCreatorPage"; import PostCreatorPage from "../Pages/PostCreatorPage/PostCreatorPage";
import RandomPostsPage from "../Pages/RandomPostsPage/RandomPostsPage"; import RandomPostsPage from "../Pages/RandomPostsPage/RandomPostsPage";
import UserBlogsPage from "../Pages/UserBlogsPage/UserBlogsPage"; import UserBlogsPage from "../Pages/UserBlogsPage/UserBlogsPage";
import UserPostsPage from "../Pages/UserPostsPage/UserPostsPage";
import UserProfilePage from "../Pages/UserProfilePage/UserProfilePage";
import UserSecurityPage from "../Pages/UserSecurityPage/UserSecurityPage";
function ErrorBoundary() { function ErrorBoundary() {
let error = useRouteError(); let error = useRouteError();
@ -46,6 +50,21 @@ export const routes = createRoutesFromElements(
} }
/> />
<Route
path="profile"
element={
<AuthPageWrapper>
<ProfilePage />
</AuthPageWrapper>
}
>
<Route index element={<UserProfilePage />} />
<Route path="posts" element={<UserPostsPage />} />
<Route path='sec' element={<UserSecurityPage />} />
</Route>
<Route path="blogs/:blogId" element={<BlogPage />} /> <Route path="blogs/:blogId" element={<BlogPage />} />
<Route path="user" element={<Outlet />}> <Route path="user" element={<Outlet />}>