Visual improvements
This commit is contained in:
parent
6054bc0403
commit
ad1aff3692
@ -3,3 +3,24 @@ export type TUser = {
|
|||||||
isAdmin: boolean;
|
isAdmin: boolean;
|
||||||
id?: string | number;
|
id?: string | number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type TInfoUser = {
|
||||||
|
user_id: number;
|
||||||
|
username: string;
|
||||||
|
email: string;
|
||||||
|
createdAt: string;
|
||||||
|
is_admin: boolean;
|
||||||
|
display_name: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TProfile = {
|
||||||
|
user_id: number;
|
||||||
|
bio: string;
|
||||||
|
avatar_url: string;
|
||||||
|
website_url: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TGetUserInfoResponse = {
|
||||||
|
user_info: TInfoUser;
|
||||||
|
profile_info: TProfile;
|
||||||
|
};
|
||||||
@ -38,7 +38,7 @@ export default function ArticleViewer(props: TArticleViewer) {
|
|||||||
<>
|
<>
|
||||||
<Container size={"3"}>
|
<Container size={"3"}>
|
||||||
<div className="ql-snow ql-editor">
|
<div className="ql-snow ql-editor">
|
||||||
<Container size={"2"} className="mt-4">
|
<Container size={"2"} className="mt-0">
|
||||||
<Flex direction={"column"}>
|
<Flex direction={"column"}>
|
||||||
<Text className="mb-2" as="div" size={"9"}>
|
<Text className="mb-2" as="div" size={"9"}>
|
||||||
{data.title}
|
{data.title}
|
||||||
|
|||||||
@ -1,15 +1,18 @@
|
|||||||
|
import { Flex } from "@radix-ui/themes";
|
||||||
import CustomNavigationMenu from "./NavigationMenu/NavigationMenu";
|
import CustomNavigationMenu from "./NavigationMenu/NavigationMenu";
|
||||||
import RightButtonBar from "./RightButtonBar/RightButtonBar";
|
import RightButtonBar from "./RightButtonBar/RightButtonBar";
|
||||||
import SearchField from "./SearchField/SearchField";
|
import SearchField from "./SearchField/SearchField";
|
||||||
|
|
||||||
export default function NavBar() {
|
export default function NavBar() {
|
||||||
return (
|
return (
|
||||||
<nav className="flex justify-center pt-2 pb-2 ml-4 mr-4 flex-[1] max-h-fit">
|
<Flex className="justify-center w-full">
|
||||||
|
<nav className="flex justify-center pt-2 pb-2 ml-4 mr-4 mb-4 mt-2 flex-[1] max-h-fit max-w-[70rem]">
|
||||||
<CustomNavigationMenu />
|
<CustomNavigationMenu />
|
||||||
|
|
||||||
<SearchField />
|
<SearchField />
|
||||||
|
|
||||||
<RightButtonBar />
|
<RightButtonBar />
|
||||||
</nav>
|
</nav>
|
||||||
|
</Flex>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ export default function SearchField() {
|
|||||||
return (
|
return (
|
||||||
<div className="flex justify-center flex-1">
|
<div className="flex justify-center flex-1">
|
||||||
<TextField.Root
|
<TextField.Root
|
||||||
className="w-2/3 rounded-lg"
|
className="hidden w-2/3 rounded-lg"
|
||||||
placeholder={t("search")}
|
placeholder={t("search")}
|
||||||
>
|
>
|
||||||
<TextField.Slot>
|
<TextField.Slot>
|
||||||
|
|||||||
@ -38,10 +38,7 @@ export default function ProfileNavbar() {
|
|||||||
<UserCard />
|
<UserCard />
|
||||||
|
|
||||||
<Box className="mx-2">
|
<Box className="mx-2">
|
||||||
<Separator
|
<Separator orientation={"horizontal"} size={"4"} />
|
||||||
orientation={"horizontal"}
|
|
||||||
size={"4"}
|
|
||||||
/>
|
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Flex gap={"2"} direction={"column"}>
|
<Flex gap={"2"} direction={"column"}>
|
||||||
|
|||||||
@ -1,8 +1,18 @@
|
|||||||
import { Avatar, Badge, Card, Flex, Separator, Text } from "@radix-ui/themes";
|
import {
|
||||||
|
Avatar,
|
||||||
|
Badge,
|
||||||
|
Card,
|
||||||
|
Flex,
|
||||||
|
Separator,
|
||||||
|
Skeleton,
|
||||||
|
Text,
|
||||||
|
} from "@radix-ui/themes";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import { useAtomValue } from "jotai";
|
import { useAtomValue } from "jotai";
|
||||||
|
import { TGetUserInfoResponse } from "../../@types/UserType";
|
||||||
import { userAtom } from "../../AtomStore/AtomStore";
|
import { userAtom } from "../../AtomStore/AtomStore";
|
||||||
import { axiosLocalhost } from "../../api/axios/axios";
|
import { axiosLocalhost } from "../../api/axios/axios";
|
||||||
|
import { JSONWithInt64 } from "../../utils/idnex";
|
||||||
|
|
||||||
type TUserCard = {
|
type TUserCard = {
|
||||||
username?: string;
|
username?: string;
|
||||||
@ -12,13 +22,22 @@ type TUserCard = {
|
|||||||
export default function UserCard(props: TUserCard) {
|
export default function UserCard(props: TUserCard) {
|
||||||
const user = useAtomValue(userAtom);
|
const user = useAtomValue(userAtom);
|
||||||
|
|
||||||
const { data } = useQuery({
|
const { data, isLoading } = useQuery({
|
||||||
queryKey: [`userCard${props.userId}`],
|
queryKey: [`userCard${props.userId || user?.id}`],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const response = await axiosLocalhost.get(`/users/${props.userId}`);
|
const response = await axiosLocalhost.get(
|
||||||
return response.data;
|
`/users/info/${props.userId || user?.id?.toString()}`,
|
||||||
|
{
|
||||||
|
transformResponse: [(data) => data],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const parsedResponse = JSONWithInt64(response.data);
|
||||||
|
|
||||||
|
console.log("parsedResponse", parsedResponse);
|
||||||
|
|
||||||
|
return parsedResponse as TGetUserInfoResponse;
|
||||||
},
|
},
|
||||||
enabled: !!props.userId,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const getInitials = (username: string): string => {
|
const getInitials = (username: string): string => {
|
||||||
@ -42,11 +61,22 @@ export default function UserCard(props: TUserCard) {
|
|||||||
<Avatar
|
<Avatar
|
||||||
fallback={<div>{getInitials(getUsername())}</div>}
|
fallback={<div>{getInitials(getUsername())}</div>}
|
||||||
radius="full"
|
radius="full"
|
||||||
|
loading="lazy"
|
||||||
/>
|
/>
|
||||||
<Flex className="flex-col ">
|
<Flex className="flex-col overflow-hidden">
|
||||||
<Text>Test User</Text>
|
{isLoading ? (
|
||||||
|
<Skeleton>
|
||||||
|
<Text truncate>{`Temporal`}</Text>
|
||||||
|
</Skeleton>
|
||||||
|
) : (
|
||||||
|
<Text truncate>
|
||||||
|
{data?.user_info.display_name ||
|
||||||
|
`Non specified`}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
|
||||||
<Text size={"1"} color={"gray"}>
|
<Text size={"1"} color={"gray"}>
|
||||||
@testuser123
|
{`@${getUsername()}`}
|
||||||
</Text>
|
</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import { Link, useNavigate } from "react-router-dom";
|
|||||||
import { axiosLocalhost } from "../../../api/axios/axios";
|
import { axiosLocalhost } from "../../../api/axios/axios";
|
||||||
import { userAtom } from "../../../AtomStore/AtomStore";
|
import { userAtom } from "../../../AtomStore/AtomStore";
|
||||||
import UseCapsLock from "../../../hooks/useCapsLock";
|
import UseCapsLock from "../../../hooks/useCapsLock";
|
||||||
|
import { JSONWithInt64 } from "../../../utils/idnex";
|
||||||
import ShowPasswordButton from "../ShowPasswordButton/ShowPasswordButton";
|
import ShowPasswordButton from "../ShowPasswordButton/ShowPasswordButton";
|
||||||
|
|
||||||
type TLoginData = {
|
type TLoginData = {
|
||||||
@ -28,12 +29,18 @@ export default function LoginPage() {
|
|||||||
mutationFn: async (data: TLoginData) => {
|
mutationFn: async (data: TLoginData) => {
|
||||||
let response = await axiosLocalhost.post(
|
let response = await axiosLocalhost.post(
|
||||||
"/login",
|
"/login",
|
||||||
JSON.stringify(data)
|
JSON.stringify(data),
|
||||||
|
{
|
||||||
|
transformResponse: [data => data]
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const parsedData = JSONWithInt64(response.data);
|
||||||
|
|
||||||
setUserAtom({
|
setUserAtom({
|
||||||
username: response.data.username,
|
username: parsedData.username,
|
||||||
isAdmin: false,
|
isAdmin: false,
|
||||||
id: response.data.id,
|
id: parsedData.id,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import { Link, useNavigate } from "react-router-dom";
|
|||||||
import { axiosLocalhost } from "../../../api/axios/axios";
|
import { axiosLocalhost } from "../../../api/axios/axios";
|
||||||
import { userAtom } from "../../../AtomStore/AtomStore";
|
import { userAtom } from "../../../AtomStore/AtomStore";
|
||||||
import UseCapsLock from "../../../hooks/useCapsLock";
|
import UseCapsLock from "../../../hooks/useCapsLock";
|
||||||
|
import { JSONWithInt64 } from "../../../utils/idnex";
|
||||||
import ShowPasswordButton from "../ShowPasswordButton/ShowPasswordButton";
|
import ShowPasswordButton from "../ShowPasswordButton/ShowPasswordButton";
|
||||||
|
|
||||||
type TRegisterData = {
|
type TRegisterData = {
|
||||||
@ -31,11 +32,16 @@ export default function RegisterPage() {
|
|||||||
|
|
||||||
const registerMutation = useMutation({
|
const registerMutation = useMutation({
|
||||||
mutationFn: async (data: TRegisterData) => {
|
mutationFn: async (data: TRegisterData) => {
|
||||||
let response = await axiosLocalhost.post("/users", JSON.stringify(data));
|
let response = await axiosLocalhost.post("/users", JSON.stringify(data), {
|
||||||
|
transformResponse: [data => data]
|
||||||
|
});
|
||||||
|
|
||||||
|
const parsedResponse = JSONWithInt64(response.data)
|
||||||
|
|
||||||
setUserAtom({
|
setUserAtom({
|
||||||
username: response.data.username,
|
username: parsedResponse.username,
|
||||||
isAdmin: false,
|
isAdmin: false,
|
||||||
id: response.data.id,
|
id: parsedResponse.id,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@ export default function UserBlogsPage() {
|
|||||||
transformResponse: [(data) => data],
|
transformResponse: [(data) => data],
|
||||||
});
|
});
|
||||||
|
|
||||||
let temp = JSONWithInt64(response.data);
|
const temp = JSONWithInt64(response.data);
|
||||||
|
|
||||||
return temp as any[];
|
return temp as any[];
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,5 +1,13 @@
|
|||||||
import { Flex, ScrollArea, Text } from "@radix-ui/themes";
|
import {
|
||||||
import { loremText } from "../../constants/loremText";
|
Badge,
|
||||||
|
Box,
|
||||||
|
DataList,
|
||||||
|
Flex,
|
||||||
|
ScrollArea,
|
||||||
|
Separator,
|
||||||
|
Text,
|
||||||
|
TextArea,
|
||||||
|
} from "@radix-ui/themes";
|
||||||
|
|
||||||
export default function UserProfilePage() {
|
export default function UserProfilePage() {
|
||||||
return (
|
return (
|
||||||
@ -7,11 +15,68 @@ export default function UserProfilePage() {
|
|||||||
<ScrollArea
|
<ScrollArea
|
||||||
type="auto"
|
type="auto"
|
||||||
scrollbars="vertical"
|
scrollbars="vertical"
|
||||||
className="flex-grow-[1] pr-5"
|
className="flex-grow-[1] pt-4"
|
||||||
>
|
>
|
||||||
<Text>
|
<Text size={"8"}>Base info</Text>
|
||||||
<p className="text-justify">{loremText}</p>
|
|
||||||
|
<Separator className="w-full my-4" />
|
||||||
|
|
||||||
|
<Box className="mb-8">
|
||||||
|
<DataList.Root size={"3"}>
|
||||||
|
<DataList.Item className="items-center">
|
||||||
|
<DataList.Label className="min-w-40">
|
||||||
|
Username
|
||||||
|
</DataList.Label>
|
||||||
|
<DataList.Value>
|
||||||
|
@Definitely_fake_user
|
||||||
|
</DataList.Value>
|
||||||
|
</DataList.Item>
|
||||||
|
<DataList.Item>
|
||||||
|
<DataList.Label className="min-w-40">
|
||||||
|
Email
|
||||||
|
</DataList.Label>
|
||||||
|
<DataList.Value>fake@email.com</DataList.Value>
|
||||||
|
</DataList.Item>
|
||||||
|
<DataList.Item>
|
||||||
|
<DataList.Label className="min-w-40">
|
||||||
|
Display name
|
||||||
|
</DataList.Label>
|
||||||
|
<DataList.Value>Isaev</DataList.Value>
|
||||||
|
</DataList.Item>
|
||||||
|
<DataList.Item>
|
||||||
|
<DataList.Label className="min-w-40">
|
||||||
|
Badges
|
||||||
|
</DataList.Label>
|
||||||
|
<DataList.Value>
|
||||||
|
<Flex
|
||||||
|
gap={"2"}
|
||||||
|
wrap={"wrap"}
|
||||||
|
className="content-evenly"
|
||||||
|
>
|
||||||
|
<Badge size={"3"}>User</Badge>
|
||||||
|
<Badge size={"3"} color="red">
|
||||||
|
Admin
|
||||||
|
</Badge>
|
||||||
|
<Badge size={"3"} color="green">
|
||||||
|
Writer
|
||||||
|
</Badge>
|
||||||
|
</Flex>
|
||||||
|
</DataList.Value>
|
||||||
|
</DataList.Item>
|
||||||
|
</DataList.Root>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Text size={"8"}>
|
||||||
|
Bio
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
|
<Separator className="w-full my-4" />
|
||||||
|
|
||||||
|
<TextArea resize={"vertical"} placeholder="Add your bio here...">
|
||||||
|
|
||||||
|
</TextArea>
|
||||||
|
|
||||||
|
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import { Outlet } from "react-router-dom";
|
|||||||
import { axiosLocalhost } from "../../api/axios/axios";
|
import { axiosLocalhost } from "../../api/axios/axios";
|
||||||
import { userAtom } from "../../AtomStore/AtomStore";
|
import { userAtom } from "../../AtomStore/AtomStore";
|
||||||
import NavBar from "../../Components/NavBar/NavBar";
|
import NavBar from "../../Components/NavBar/NavBar";
|
||||||
|
import { JSONWithInt64 } from "../../utils/idnex";
|
||||||
|
|
||||||
const REFETCH_INTERVAL_IN_MINUTES = 5;
|
const REFETCH_INTERVAL_IN_MINUTES = 5;
|
||||||
const RETRY_INTERVAL_IN_SECONDS = 1;
|
const RETRY_INTERVAL_IN_SECONDS = 1;
|
||||||
@ -19,12 +20,16 @@ export default function MainPage() {
|
|||||||
queryKey: ["authKey"],
|
queryKey: ["authKey"],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
try {
|
try {
|
||||||
const response = await axiosLocalhost.get("/auth/check");
|
const response = await axiosLocalhost.get("/auth/check", {
|
||||||
|
transformResponse: [data => data]
|
||||||
|
});
|
||||||
|
|
||||||
|
const parsedResponse = JSONWithInt64(response.data)
|
||||||
|
|
||||||
setUserData({
|
setUserData({
|
||||||
isAdmin: response.data["is_admin"],
|
isAdmin: parsedResponse["is_admin"],
|
||||||
username: response.data["username"],
|
username: parsedResponse["username"],
|
||||||
id: response.data["id"],
|
id: parsedResponse["id"],
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@ -8,12 +8,13 @@ export default function ProfilePage() {
|
|||||||
className={`
|
className={`
|
||||||
relative flex-col flex-1 gap-0 mx-4
|
relative flex-col flex-1 gap-0 mx-4
|
||||||
sm:flex-row sm:gap-4
|
sm:flex-row sm:gap-4
|
||||||
md:w-full md:min-w-[45rem] md:max-w-[50rem] md:mx-auto
|
md:w-full md:min-w-[45rem] md:max-w-[70rem] md:mx-auto
|
||||||
lg:min-w-[50rem] lg:mx-auto
|
|
||||||
overflow-hidden
|
overflow-hidden
|
||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
|
<Box className="">
|
||||||
<ProfileNavbar />
|
<ProfileNavbar />
|
||||||
|
</Box>
|
||||||
|
|
||||||
<Box className="my-2 collapse sm:visible">
|
<Box className="my-2 collapse sm:visible">
|
||||||
<Separator orientation="vertical" size={"4"} />
|
<Separator orientation="vertical" size={"4"} />
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.27.0
|
// sqlc v1.28.0
|
||||||
// source: blogs_queries.sql
|
// source: blogs_queries.sql
|
||||||
|
|
||||||
package db_repo
|
package db_repo
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.27.0
|
// sqlc v1.28.0
|
||||||
// source: bookmarks_queries.sql
|
// source: bookmarks_queries.sql
|
||||||
|
|
||||||
package db_repo
|
package db_repo
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.27.0
|
// sqlc v1.28.0
|
||||||
// source: categories_queries.sql
|
// source: categories_queries.sql
|
||||||
|
|
||||||
package db_repo
|
package db_repo
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.27.0
|
// sqlc v1.28.0
|
||||||
// source: comments_queries.sql
|
// source: comments_queries.sql
|
||||||
|
|
||||||
package db_repo
|
package db_repo
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.27.0
|
// sqlc v1.28.0
|
||||||
|
|
||||||
package db_repo
|
package db_repo
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.27.0
|
// sqlc v1.28.0
|
||||||
// source: favorites_queries.sql
|
// source: favorites_queries.sql
|
||||||
|
|
||||||
package db_repo
|
package db_repo
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.27.0
|
// sqlc v1.28.0
|
||||||
// source: likes_queries.sql
|
// source: likes_queries.sql
|
||||||
|
|
||||||
package db_repo
|
package db_repo
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.27.0
|
// sqlc v1.28.0
|
||||||
|
|
||||||
package db_repo
|
package db_repo
|
||||||
|
|
||||||
@ -89,4 +89,5 @@ type User struct {
|
|||||||
Password string `json:"password" validate:"required"`
|
Password string `json:"password" validate:"required"`
|
||||||
CreatedAt pgtype.Timestamp `json:"created_at"`
|
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||||
IsAdmin bool `json:"is_admin"`
|
IsAdmin bool `json:"is_admin"`
|
||||||
|
DisplayName pgtype.Text `json:"display_name"`
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.27.0
|
// sqlc v1.28.0
|
||||||
// source: multi_queries.sql
|
// source: multi_queries.sql
|
||||||
|
|
||||||
package db_repo
|
package db_repo
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.27.0
|
// sqlc v1.28.0
|
||||||
// source: post_tags_queries.sql
|
// source: post_tags_queries.sql
|
||||||
|
|
||||||
package db_repo
|
package db_repo
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.27.0
|
// sqlc v1.28.0
|
||||||
// source: post_votes_queries.sql
|
// source: post_votes_queries.sql
|
||||||
|
|
||||||
package db_repo
|
package db_repo
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.27.0
|
// sqlc v1.28.0
|
||||||
// source: posts_queries.sql
|
// source: posts_queries.sql
|
||||||
|
|
||||||
package db_repo
|
package db_repo
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.27.0
|
// sqlc v1.28.0
|
||||||
// source: profiles_queries.sql
|
// source: profiles_queries.sql
|
||||||
|
|
||||||
package db_repo
|
package db_repo
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.27.0
|
// sqlc v1.28.0
|
||||||
// source: tags_queries.sql
|
// source: tags_queries.sql
|
||||||
|
|
||||||
package db_repo
|
package db_repo
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.27.0
|
// sqlc v1.28.0
|
||||||
// source: users_queries.sql
|
// source: users_queries.sql
|
||||||
|
|
||||||
package db_repo
|
package db_repo
|
||||||
@ -13,7 +13,7 @@ const createUser = `-- name: CreateUser :one
|
|||||||
INSERT INTO public.users
|
INSERT INTO public.users
|
||||||
(user_id, username, email, "password", created_at, is_admin)
|
(user_id, username, email, "password", created_at, is_admin)
|
||||||
VALUES($1, $2, $3, $4, CURRENT_TIMESTAMP, false)
|
VALUES($1, $2, $3, $4, CURRENT_TIMESTAMP, false)
|
||||||
RETURNING user_id, username, email, password, created_at, is_admin
|
RETURNING user_id, username, email, password, created_at, is_admin, display_name
|
||||||
`
|
`
|
||||||
|
|
||||||
type CreateUserParams struct {
|
type CreateUserParams struct {
|
||||||
@ -38,6 +38,7 @@ func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) (User, e
|
|||||||
&i.Password,
|
&i.Password,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.IsAdmin,
|
&i.IsAdmin,
|
||||||
|
&i.DisplayName,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
@ -63,7 +64,7 @@ func (q *Queries) DeleteUserByUsername(ctx context.Context, username string) err
|
|||||||
}
|
}
|
||||||
|
|
||||||
const getAllUsers = `-- name: GetAllUsers :many
|
const getAllUsers = `-- name: GetAllUsers :many
|
||||||
SELECT user_id, username, email, password, created_at, is_admin FROM users
|
SELECT user_id, username, email, password, created_at, is_admin, display_name FROM users
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) GetAllUsers(ctx context.Context) ([]User, error) {
|
func (q *Queries) GetAllUsers(ctx context.Context) ([]User, error) {
|
||||||
@ -82,6 +83,7 @@ func (q *Queries) GetAllUsers(ctx context.Context) ([]User, error) {
|
|||||||
&i.Password,
|
&i.Password,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.IsAdmin,
|
&i.IsAdmin,
|
||||||
|
&i.DisplayName,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -94,7 +96,7 @@ func (q *Queries) GetAllUsers(ctx context.Context) ([]User, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const getUserByEmailOrNickname = `-- name: GetUserByEmailOrNickname :one
|
const getUserByEmailOrNickname = `-- name: GetUserByEmailOrNickname :one
|
||||||
SELECT user_id, username, email, password, created_at, is_admin FROM users WHERE username = $1 OR email = $2 LIMIT 1
|
SELECT user_id, username, email, password, created_at, is_admin, display_name FROM users WHERE username = $1 OR email = $2 LIMIT 1
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetUserByEmailOrNicknameParams struct {
|
type GetUserByEmailOrNicknameParams struct {
|
||||||
@ -112,12 +114,13 @@ func (q *Queries) GetUserByEmailOrNickname(ctx context.Context, arg GetUserByEma
|
|||||||
&i.Password,
|
&i.Password,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.IsAdmin,
|
&i.IsAdmin,
|
||||||
|
&i.DisplayName,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const getUserById = `-- name: GetUserById :one
|
const getUserById = `-- name: GetUserById :one
|
||||||
SELECT user_id, username, email, password, created_at, is_admin FROM users WHERE user_id = $1
|
SELECT user_id, username, email, password, created_at, is_admin, display_name FROM users WHERE user_id = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) GetUserById(ctx context.Context, userID int64) (User, error) {
|
func (q *Queries) GetUserById(ctx context.Context, userID int64) (User, error) {
|
||||||
@ -130,12 +133,13 @@ func (q *Queries) GetUserById(ctx context.Context, userID int64) (User, error) {
|
|||||||
&i.Password,
|
&i.Password,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.IsAdmin,
|
&i.IsAdmin,
|
||||||
|
&i.DisplayName,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const getUserByUsername = `-- name: GetUserByUsername :one
|
const getUserByUsername = `-- name: GetUserByUsername :one
|
||||||
SELECT user_id, username, email, password, created_at, is_admin FROM users WHERE username = $1
|
SELECT user_id, username, email, password, created_at, is_admin, display_name FROM users WHERE username = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) GetUserByUsername(ctx context.Context, username string) (User, error) {
|
func (q *Queries) GetUserByUsername(ctx context.Context, username string) (User, error) {
|
||||||
@ -148,6 +152,7 @@ func (q *Queries) GetUserByUsername(ctx context.Context, username string) (User,
|
|||||||
&i.Password,
|
&i.Password,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.IsAdmin,
|
&i.IsAdmin,
|
||||||
|
&i.DisplayName,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
@ -167,7 +172,7 @@ const updateUserPasswordHash = `-- name: UpdateUserPasswordHash :one
|
|||||||
UPDATE public.users
|
UPDATE public.users
|
||||||
SET "password"=$1
|
SET "password"=$1
|
||||||
WHERE user_id=$2
|
WHERE user_id=$2
|
||||||
RETURNING user_id, username, email, password, created_at, is_admin
|
RETURNING user_id, username, email, password, created_at, is_admin, display_name
|
||||||
`
|
`
|
||||||
|
|
||||||
type UpdateUserPasswordHashParams struct {
|
type UpdateUserPasswordHashParams struct {
|
||||||
@ -185,6 +190,7 @@ func (q *Queries) UpdateUserPasswordHash(ctx context.Context, arg UpdateUserPass
|
|||||||
&i.Password,
|
&i.Password,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.IsAdmin,
|
&i.IsAdmin,
|
||||||
|
&i.DisplayName,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ COMMENT ON SCHEMA "public" IS 'standard public schema';
|
|||||||
-- Create "categories" table
|
-- Create "categories" table
|
||||||
CREATE TABLE "public"."categories" ("category_id" integer NOT NULL, "category_name" character varying(50) NOT NULL, PRIMARY KEY ("category_id"), CONSTRAINT "categories_category_name_key" UNIQUE ("category_name"));
|
CREATE TABLE "public"."categories" ("category_id" integer NOT NULL, "category_name" character varying(50) NOT NULL, PRIMARY KEY ("category_id"), CONSTRAINT "categories_category_name_key" UNIQUE ("category_name"));
|
||||||
-- Create "users" table
|
-- Create "users" table
|
||||||
CREATE TABLE "public"."users" ("user_id" bigint NOT NULL, "username" character varying(50) NOT NULL, "email" character varying(100) NOT NULL, "password" character varying(255) NOT NULL, "created_at" timestamp NULL DEFAULT CURRENT_TIMESTAMP, "is_admin" boolean NOT NULL, PRIMARY KEY ("user_id"), CONSTRAINT "users_email_key" UNIQUE ("email"), CONSTRAINT "users_username_key" UNIQUE ("username"));
|
CREATE TABLE "public"."users" ("user_id" bigint NOT NULL, "username" character varying(50) NOT NULL, "email" character varying(100) NOT NULL, "password" character varying(255) NOT NULL, "created_at" timestamp NULL DEFAULT CURRENT_TIMESTAMP, "is_admin" boolean NOT NULL, "display_name" character varying(32) NULL, PRIMARY KEY ("user_id"), CONSTRAINT "users_email_key" UNIQUE ("email"), CONSTRAINT "users_username_key" UNIQUE ("username"));
|
||||||
-- Create "blogs" table
|
-- Create "blogs" table
|
||||||
CREATE TABLE "public"."blogs" ("blog_id" bigint NOT NULL, "user_id" bigint NOT NULL, "title" character varying(255) NULL, "description" text NULL, "category_id" integer NULL, "created_at" timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY ("blog_id"), CONSTRAINT "blogs_category_id_fkey" FOREIGN KEY ("category_id") REFERENCES "public"."categories" ("category_id") ON UPDATE NO ACTION ON DELETE NO ACTION, CONSTRAINT "blogs_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE CASCADE);
|
CREATE TABLE "public"."blogs" ("blog_id" bigint NOT NULL, "user_id" bigint NOT NULL, "title" character varying(255) NULL, "description" text NULL, "category_id" integer NULL, "created_at" timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY ("blog_id"), CONSTRAINT "blogs_category_id_fkey" FOREIGN KEY ("category_id") REFERENCES "public"."categories" ("category_id") ON UPDATE NO ACTION ON DELETE NO ACTION, CONSTRAINT "blogs_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE CASCADE);
|
||||||
-- Create "posts" table
|
-- Create "posts" table
|
||||||
@ -23,7 +23,7 @@ CREATE TABLE "public"."tags" ("tag_id" integer NOT NULL, "tag_name" character va
|
|||||||
-- Create "post_tags" table
|
-- Create "post_tags" table
|
||||||
CREATE TABLE "public"."post_tags" ("post_id" bigint NOT NULL, "tag_id" integer NOT NULL, PRIMARY KEY ("post_id", "tag_id"), CONSTRAINT "post_tags_post_id_fkey" FOREIGN KEY ("post_id") REFERENCES "public"."posts" ("post_id") ON UPDATE NO ACTION ON DELETE CASCADE, CONSTRAINT "post_tags_tag_id_fkey" FOREIGN KEY ("tag_id") REFERENCES "public"."tags" ("tag_id") ON UPDATE NO ACTION ON DELETE CASCADE);
|
CREATE TABLE "public"."post_tags" ("post_id" bigint NOT NULL, "tag_id" integer NOT NULL, PRIMARY KEY ("post_id", "tag_id"), CONSTRAINT "post_tags_post_id_fkey" FOREIGN KEY ("post_id") REFERENCES "public"."posts" ("post_id") ON UPDATE NO ACTION ON DELETE CASCADE, CONSTRAINT "post_tags_tag_id_fkey" FOREIGN KEY ("tag_id") REFERENCES "public"."tags" ("tag_id") ON UPDATE NO ACTION ON DELETE CASCADE);
|
||||||
-- Create "post_votes" table
|
-- Create "post_votes" table
|
||||||
CREATE TABLE "public"."post_votes" ("post_id" bigint NOT NULL, "user_id" bigint NOT NULL, "vote" boolean NOT NULL, PRIMARY KEY ("post_id", "user_id"), CONSTRAINT "post_votes_post_id_fkey" FOREIGN KEY ("post_id") REFERENCES "public"."posts" ("post_id") ON UPDATE NO ACTION ON DELETE NO ACTION, CONSTRAINT "post_votes_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE NO ACTION);
|
CREATE TABLE "public"."post_votes" ("post_id" bigint NOT NULL, "user_id" bigint NOT NULL, "vote" boolean NOT NULL, PRIMARY KEY ("post_id", "user_id"), CONSTRAINT "post_votes_post_id_fkey" FOREIGN KEY ("post_id") REFERENCES "public"."posts" ("post_id") ON UPDATE NO ACTION ON DELETE CASCADE, CONSTRAINT "post_votes_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE NO ACTION);
|
||||||
-- Create "profiles" table
|
-- Create "profiles" table
|
||||||
CREATE TABLE "public"."profiles" ("user_id" bigint NOT NULL, "bio" text NULL, "avatar_url" character varying(255) NULL, "website_url" character varying(100) NULL, PRIMARY KEY ("user_id"), CONSTRAINT "profiles_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE CASCADE);
|
CREATE TABLE "public"."profiles" ("user_id" bigint NOT NULL, "bio" text NULL, "avatar_url" character varying(255) NULL, "website_url" character varying(100) NULL, PRIMARY KEY ("user_id"), CONSTRAINT "profiles_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("user_id") ON UPDATE NO ACTION ON DELETE CASCADE);
|
||||||
-- Create index "profiles_user_id_idx" to table: "profiles"
|
-- Create index "profiles_user_id_idx" to table: "profiles"
|
||||||
|
|||||||
@ -22,7 +22,7 @@ func TargetMiddleware() gin.HandlerFunc {
|
|||||||
case "POST":
|
case "POST":
|
||||||
c.Set("target", POST)
|
c.Set("target", POST)
|
||||||
case "GET":
|
case "GET":
|
||||||
c.Set("target", DELETE)
|
c.Set("target", GET)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Next()
|
c.Next()
|
||||||
|
|||||||
@ -16,7 +16,7 @@ func GetClaimsFromContext(c *gin.Context) (auth.UserInfoJWT, error) {
|
|||||||
claims, exists := c.Get(global.ContextTokenData)
|
claims, exists := c.Get(global.ContextTokenData)
|
||||||
|
|
||||||
if !exists {
|
if !exists {
|
||||||
return auth.UserInfoJWT{}, fmt.Errorf("error getting user id")
|
return auth.UserInfoJWT{}, fmt.Errorf("error getting user id 1")
|
||||||
}
|
}
|
||||||
|
|
||||||
parsedUserId, err := strconv.ParseInt(
|
parsedUserId, err := strconv.ParseInt(
|
||||||
|
|||||||
@ -12,7 +12,7 @@ func GetUserIdFromContext(c *gin.Context) (int64, error) {
|
|||||||
userId, exists := c.Get(global.ContextUserId)
|
userId, exists := c.Get(global.ContextUserId)
|
||||||
|
|
||||||
if !exists {
|
if !exists {
|
||||||
return -1, fmt.Errorf("error getting user id")
|
return -1, fmt.Errorf("error getting user id 2")
|
||||||
}
|
}
|
||||||
|
|
||||||
if parsedUserId, err := strconv.ParseInt(userId.(string), 10, 64); err != nil {
|
if parsedUserId, err := strconv.ParseInt(userId.(string), 10, 64); err != nil {
|
||||||
|
|||||||
@ -14,6 +14,7 @@ const (
|
|||||||
POST_BLOG_MIDDLEWARE = "POST_BLOG_MIDDLEWARE"
|
POST_BLOG_MIDDLEWARE = "POST_BLOG_MIDDLEWARE"
|
||||||
POST_VOTE_MIDDLEWARE = "POST_VOTE_MIDDLEWARE"
|
POST_VOTE_MIDDLEWARE = "POST_VOTE_MIDDLEWARE"
|
||||||
POST_VOTES_MIDDLEWARE = "POST_VOTES_MIDDLEWARE"
|
POST_VOTES_MIDDLEWARE = "POST_VOTES_MIDDLEWARE"
|
||||||
|
USER_MIDDLEWARE = "USER_MIDDLEWARE"
|
||||||
)
|
)
|
||||||
|
|
||||||
var MiddlewareProvider = middleware.MiddlewareProvider{
|
var MiddlewareProvider = middleware.MiddlewareProvider{
|
||||||
@ -152,6 +153,25 @@ var policiesToRegister = map[string]middleware.RulesToCheck{
|
|||||||
MustBeCompleted: rules.ALL_RULES_MUST_BE_COMPLETED,
|
MustBeCompleted: rules.ALL_RULES_MUST_BE_COMPLETED,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
USER_MIDDLEWARE: {
|
||||||
|
middleware.GET: {
|
||||||
|
Rules: make([]rules.RuleFunction, 0),
|
||||||
|
MustBeCompleted: rules.ALL_RULES_MUST_BE_COMPLETED,
|
||||||
|
},
|
||||||
|
middleware.PUT: {
|
||||||
|
Rules: []rules.RuleFunction{
|
||||||
|
globalrules.AuthorizedRule,
|
||||||
|
},
|
||||||
|
MustBeCompleted: rules.ALL_RULES_MUST_BE_COMPLETED,
|
||||||
|
},
|
||||||
|
middleware.DELETE: {
|
||||||
|
Rules: []rules.RuleFunction{
|
||||||
|
globalrules.IsAdminRule,
|
||||||
|
},
|
||||||
|
MustBeCompleted: rules.ALL_RULES_MUST_BE_COMPLETED,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitMiddlewareProvider() {
|
func InitMiddlewareProvider() {
|
||||||
|
|||||||
@ -194,6 +194,14 @@ func SetupRotes(g *gin.Engine) error {
|
|||||||
voteroutes.GetVotes,
|
voteroutes.GetVotes,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
userGroup := g.Group("/users/")
|
||||||
|
userGroup.Use(MiddlewareProvider.GetMiddleware(USER_MIDDLEWARE))
|
||||||
|
|
||||||
|
userGroup.GET(
|
||||||
|
"/info/:user-id",
|
||||||
|
userroutes.GetUserInfo,
|
||||||
|
)
|
||||||
|
|
||||||
// Admin group routes
|
// Admin group routes
|
||||||
adminGroup := g.Group("/admin/")
|
adminGroup := g.Group("/admin/")
|
||||||
adminGroup.Use(middleware.AdminMiddleware())
|
adminGroup.Use(middleware.AdminMiddleware())
|
||||||
|
|||||||
35
enshi_back/routes/userRoutes/getUserInfo.go
Normal file
35
enshi_back/routes/userRoutes/getUserInfo.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package userroutes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
db_repo "enshi/db/go_queries"
|
||||||
|
"enshi/db_connection"
|
||||||
|
"enshi/middleware/getters"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetUserInfo(c *gin.Context) {
|
||||||
|
userId, err := getters.GetInt64Param(c, "user-id")
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, gin.H{"error": "Invalid user ID"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
userInfo, err := db_repo.New(db_connection.Dbx).GetUserById(context.Background(), userId)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(500, gin.H{"error": "Failed to retrieve user information"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
userProfileInfo, err := db_repo.New(db_connection.Dbx).GetProfileByUserId(context.Background(), userId)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(500, gin.H{"error": "Failed to retrieve user profile information"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(200, gin.H{
|
||||||
|
"user_info": userInfo,
|
||||||
|
"profile_info": userProfileInfo,
|
||||||
|
})
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user