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 {
|
||||
createRoutesFromElements,
|
||||
Outlet,
|
||||
Route,
|
||||
useRouteError,
|
||||
} from "react-router-dom";
|
||||
import ArticleViewer from "../Components/ArticleViewer/ArticleViewer";
|
||||
import MainPage from "../layout/MainPage/MainPage";
|
||||
import AuthPageWrapper from "../Pages/AuthPageWrapper/AuthPageWrapper";
|
||||
import BlogPage from "../Pages/BlogPage/BlogPage";
|
||||
import LoginPage from "../Pages/LoginRegisterPage/LoginPage/LoginPage";
|
||||
import PostRedactor from "../Pages/LoginRegisterPage/PostRedactor/PostRedactor";
|
||||
import RegisterPage from "../Pages/LoginRegisterPage/RegisterPage/RegisterPage";
|
||||
import MainPage from "../Pages/MainPage/MainPage";
|
||||
import PostCreatorPage from "../Pages/PostCreatorPage/PostCreatorPage";
|
||||
import RandomPostsPage from "../Pages/RandomPostsPage/RandomPostsPage";
|
||||
import UserBlogsPage from "../Pages/UserBlogsPage/UserBlogsPage";
|
||||
|
||||
function ErrorBoundary() {
|
||||
let error = useRouteError();
|
||||
@ -26,14 +29,16 @@ export const routes = createRoutesFromElements(
|
||||
<Route index element={<RandomPostsPage />} />
|
||||
|
||||
<Route
|
||||
path="/a?/c"
|
||||
path="a?/c"
|
||||
element={
|
||||
<Text weight={"regular"}>This page is yet to be created</Text>
|
||||
<Text weight={"regular"}>
|
||||
This page is yet to be created
|
||||
</Text>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/create"
|
||||
path="create"
|
||||
element={
|
||||
<AuthPageWrapper>
|
||||
<PostCreatorPage />
|
||||
@ -41,8 +46,21 @@ export const routes = createRoutesFromElements(
|
||||
}
|
||||
/>
|
||||
|
||||
<Route path="/posts/:postId" element={<ArticleViewer />} />
|
||||
<Route path="/posts/change/:postId" element={<PostRedactor />} />
|
||||
<Route path="blogs/:blogId" element={<BlogPage />} />
|
||||
|
||||
<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
|
||||
|
||||
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.GET("check", testAuth)
|
||||
|
||||
temporal := g.Group("/")
|
||||
temporal.Use(middleware.AuthMiddleware())
|
||||
temporal.GET(
|
||||
"/user/blogs",
|
||||
blogRoutes.GetUserBlogs,
|
||||
)
|
||||
|
||||
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