Blogs
This commit is contained in:
parent
1f7d95a4ff
commit
d87663d3d4
13
enshi/src/Pages/BlogPage/BlogPage.tsx
Normal file
13
enshi/src/Pages/BlogPage/BlogPage.tsx
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { Box } from '@radix-ui/themes'
|
||||||
|
import { useParams } from 'react-router-dom'
|
||||||
|
|
||||||
|
|
||||||
|
export default function BlogPage() {
|
||||||
|
const queryParams = useParams()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
||||||
21
enshi/src/Pages/UserBlogsPage/BlogBox/BlogBox.tsx
Normal file
21
enshi/src/Pages/UserBlogsPage/BlogBox/BlogBox.tsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { Card } from '@radix-ui/themes';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
|
type TBlogBox = {
|
||||||
|
title?: string;
|
||||||
|
blogId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function BlogBox(props: TBlogBox) {
|
||||||
|
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card className='w-full h-20'
|
||||||
|
onClick={() => navigate(``)}
|
||||||
|
>
|
||||||
|
{props?.title || "...No title..."}
|
||||||
|
{props?.blogId || "adqwwd"}
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
import { Box, Skeleton } from "@radix-ui/themes";
|
||||||
|
|
||||||
|
export default function SkeletonBoxes() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Skeleton>
|
||||||
|
<Box className="w-full h-20 mb-2 rounded-lg"></Box>
|
||||||
|
</Skeleton>
|
||||||
|
<Skeleton>
|
||||||
|
<Box className="w-full h-20 mb-2 rounded-lg"></Box>
|
||||||
|
</Skeleton>
|
||||||
|
<Skeleton>
|
||||||
|
<Box className="w-full h-20 mb-2 rounded-lg"></Box>
|
||||||
|
</Skeleton>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
69
enshi/src/Pages/UserBlogsPage/UserBlogsPage.tsx
Normal file
69
enshi/src/Pages/UserBlogsPage/UserBlogsPage.tsx
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import { Box, Container, Flex } from "@radix-ui/themes";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import { useAtomValue } from "jotai";
|
||||||
|
import { userAtom } from "../../AtomStore/AtomStore";
|
||||||
|
import { axiosLocalhost } from "../../api/axios/axios";
|
||||||
|
import BlogBox from "./BlogBox/BlogBox";
|
||||||
|
import SkeletonBoxes from "./SkeletonBoxes/SkeletonBoxes";
|
||||||
|
|
||||||
|
export default function UserBlogsPage() {
|
||||||
|
const user = useAtomValue(userAtom);
|
||||||
|
|
||||||
|
const isBigNumber = (num: any) => !Number.isSafeInteger(+num);
|
||||||
|
|
||||||
|
const enquoteBigNumber = (jsonString: any, bigNumChecker: any) =>
|
||||||
|
jsonString.replaceAll(
|
||||||
|
/([:\s\[,]*)(\d+)([\s,\]]*)/g,
|
||||||
|
(matchingSubstr: any, prefix: any, bigNum: any, suffix: any) =>
|
||||||
|
bigNumChecker(bigNum)
|
||||||
|
? `${prefix}"${bigNum}"${suffix}`
|
||||||
|
: matchingSubstr
|
||||||
|
);
|
||||||
|
|
||||||
|
const parseWithBigInt = (jsonString: any, bigNumChecker: any) =>
|
||||||
|
JSON.parse(enquoteBigNumber(jsonString, bigNumChecker), (key, value) =>
|
||||||
|
!isNaN(value) && bigNumChecker(value)
|
||||||
|
? BigInt(value).toString()
|
||||||
|
: value
|
||||||
|
);
|
||||||
|
|
||||||
|
const { data, isPending, isFetching } = useQuery({
|
||||||
|
queryKey: ["userBlogs"],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await axiosLocalhost.get("/user/blogs", {
|
||||||
|
transformResponse: [(data) => data],
|
||||||
|
});
|
||||||
|
|
||||||
|
let temp = parseWithBigInt(response.data, isBigNumber);
|
||||||
|
|
||||||
|
return temp as any[];
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isFetching)
|
||||||
|
return (
|
||||||
|
<Container size={"1"}>
|
||||||
|
<SkeletonBoxes />
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box className="size-full">
|
||||||
|
<Container size={"1"}>
|
||||||
|
<Flex direction={"column"} gap={"2"}>
|
||||||
|
{data
|
||||||
|
? data?.map((blog: any, b) => {
|
||||||
|
return (
|
||||||
|
<BlogBox
|
||||||
|
key={b}
|
||||||
|
title={blog.title}
|
||||||
|
blogId={blog.blog_id}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
: null}
|
||||||
|
</Flex>
|
||||||
|
</Container>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,17 +1,20 @@
|
|||||||
import { Text } from "@radix-ui/themes";
|
import { Text } from "@radix-ui/themes";
|
||||||
import {
|
import {
|
||||||
createRoutesFromElements,
|
createRoutesFromElements,
|
||||||
|
Outlet,
|
||||||
Route,
|
Route,
|
||||||
useRouteError,
|
useRouteError,
|
||||||
} 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 AuthPageWrapper from "../Pages/AuthPageWrapper/AuthPageWrapper";
|
import AuthPageWrapper from "../Pages/AuthPageWrapper/AuthPageWrapper";
|
||||||
|
import BlogPage from "../Pages/BlogPage/BlogPage";
|
||||||
import LoginPage from "../Pages/LoginRegisterPage/LoginPage/LoginPage";
|
import LoginPage from "../Pages/LoginRegisterPage/LoginPage/LoginPage";
|
||||||
import PostRedactor from "../Pages/LoginRegisterPage/PostRedactor/PostRedactor";
|
import PostRedactor from "../Pages/LoginRegisterPage/PostRedactor/PostRedactor";
|
||||||
import RegisterPage from "../Pages/LoginRegisterPage/RegisterPage/RegisterPage";
|
import RegisterPage from "../Pages/LoginRegisterPage/RegisterPage/RegisterPage";
|
||||||
import MainPage from "../Pages/MainPage/MainPage";
|
|
||||||
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";
|
||||||
|
|
||||||
function ErrorBoundary() {
|
function ErrorBoundary() {
|
||||||
let error = useRouteError();
|
let error = useRouteError();
|
||||||
@ -26,14 +29,16 @@ export const routes = createRoutesFromElements(
|
|||||||
<Route index element={<RandomPostsPage />} />
|
<Route index element={<RandomPostsPage />} />
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
path="/a?/c"
|
path="a?/c"
|
||||||
element={
|
element={
|
||||||
<Text weight={"regular"}>This page is yet to be created</Text>
|
<Text weight={"regular"}>
|
||||||
|
This page is yet to be created
|
||||||
|
</Text>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
path="/create"
|
path="create"
|
||||||
element={
|
element={
|
||||||
<AuthPageWrapper>
|
<AuthPageWrapper>
|
||||||
<PostCreatorPage />
|
<PostCreatorPage />
|
||||||
@ -41,8 +46,21 @@ export const routes = createRoutesFromElements(
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Route path="/posts/:postId" element={<ArticleViewer />} />
|
<Route path="blogs/:blogId" element={<BlogPage />} />
|
||||||
<Route path="/posts/change/:postId" element={<PostRedactor />} />
|
|
||||||
|
<Route path="user" element={<Outlet />}>
|
||||||
|
<Route
|
||||||
|
path="blogs"
|
||||||
|
element={
|
||||||
|
<AuthPageWrapper>
|
||||||
|
<UserBlogsPage />
|
||||||
|
</AuthPageWrapper>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Route>
|
||||||
|
|
||||||
|
<Route path="posts/:postId" element={<ArticleViewer />} />
|
||||||
|
<Route path="posts/change/:postId" element={<PostRedactor />} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
|
|||||||
29
enshi_back/routes/blogRoutes/getUserBlogs.go
Normal file
29
enshi_back/routes/blogRoutes/getUserBlogs.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package blogRoutes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
rest_api_stuff "enshi/REST_API_stuff"
|
||||||
|
db_repo "enshi/db/go_queries"
|
||||||
|
"enshi/db_connection"
|
||||||
|
"enshi/middleware/getters"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetUserBlogs(c *gin.Context) {
|
||||||
|
userId, err := getters.GetUserIdFromContext(c)
|
||||||
|
if err != nil {
|
||||||
|
rest_api_stuff.BadRequestAnswer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
blogData, err := db_repo.New(db_connection.Dbx).
|
||||||
|
GetBlogsByUserId(context.Background(), userId)
|
||||||
|
if err != nil {
|
||||||
|
rest_api_stuff.InternalErrorAnswer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.IndentedJSON(http.StatusOK, blogData)
|
||||||
|
}
|
||||||
@ -174,5 +174,12 @@ func SetupRotes(g *gin.Engine) error {
|
|||||||
authGroup.Use(middleware.AuthMiddleware())
|
authGroup.Use(middleware.AuthMiddleware())
|
||||||
authGroup.GET("check", testAuth)
|
authGroup.GET("check", testAuth)
|
||||||
|
|
||||||
|
temporal := g.Group("/")
|
||||||
|
temporal.Use(middleware.AuthMiddleware())
|
||||||
|
temporal.GET(
|
||||||
|
"/user/blogs",
|
||||||
|
blogRoutes.GetUserBlogs,
|
||||||
|
)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
49
enshi_back/utils/cringe.go
Normal file
49
enshi_back/utils/cringe.go
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ConvertInt64ToStringInStruct(input any) (any, error) {
|
||||||
|
origVal := reflect.ValueOf(input)
|
||||||
|
|
||||||
|
// Ensure input is a struct or pointer to a struct
|
||||||
|
if origVal.Kind() == reflect.Ptr {
|
||||||
|
origVal = origVal.Elem()
|
||||||
|
}
|
||||||
|
if origVal.Kind() != reflect.Struct {
|
||||||
|
return nil, fmt.Errorf("input must be a struct or a pointer to a struct")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new instance of the same type
|
||||||
|
newStruct := reflect.New(origVal.Type()).Elem()
|
||||||
|
|
||||||
|
// Iterate through fields
|
||||||
|
for i := 0; i < origVal.NumField(); i++ {
|
||||||
|
field := origVal.Field(i)
|
||||||
|
newField := newStruct.Field(i)
|
||||||
|
|
||||||
|
if !newField.CanSet() {
|
||||||
|
// Skip unexported fields
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch field.Kind() {
|
||||||
|
case reflect.Int64:
|
||||||
|
// Convert int64 fields to string if the target is compatible
|
||||||
|
// if newField.Kind() == reflect.Int64 {
|
||||||
|
// fmt.Print("aqwrqfwq", field)
|
||||||
|
// newField.Set(strconv.FormatInt(field.Int(), 10))
|
||||||
|
// }
|
||||||
|
newField.SetString("asd")
|
||||||
|
default:
|
||||||
|
// Copy other fields directly
|
||||||
|
if newField.Type() == field.Type() {
|
||||||
|
newField.Set(field)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newStruct.Interface(), nil
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user