Skip to content
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
c093072
🚀 Add deploy yaml
lapidix Apr 27, 2025
e59907b
♻️ Refactoring code
lapidix May 1, 2025
25e1124
🥅 Fix type error
lapidix May 1, 2025
764fe76
🥅 Fix export error
lapidix May 1, 2025
45eb0dc
🔧 Udpate config file
lapidix May 1, 2025
eac905d
🥅 Fix api url error
lapidix May 1, 2025
f270f31
🔧 Modify api url
lapidix May 1, 2025
4af8b01
🔇 Remove debug logs
lapidix May 1, 2025
1b8d07c
🐛 Fix bug add post hook
lapidix May 1, 2025
c0d85f6
🚚 Rename api method
lapidix May 1, 2025
79508c3
:sparkles: implement use case interfaces for post, user, and comment …
lapidix Jun 22, 2025
6017f5b
:construction: update import path and remove package manager metadata
lapidix Jun 22, 2025
618839a
:recycle: refactor: implement domain-driven design for comment featur…
lapidix Jun 22, 2025
3bd9c8b
:recycle: implement domain-driven design for user and comment entitie…
lapidix Jun 23, 2025
268ddc8
:recycle: migrate user-related types to DTO pattern and update refer…
lapidix Jun 23, 2025
1535afc
:recycle: rename data interfaces to entity types and add address/comp…
lapidix Jun 23, 2025
a3ba0f8
:recycle: standardize file naming convention across entities and feat…
lapidix Jun 23, 2025
33fa27a
:recycle: implement domain-driven design for comment feature
lapidix Jun 23, 2025
e79da42
:recycle: implement user repository pattern and update service depend…
lapidix Jun 23, 2025
02b8665
:recycle: migrate API layer to adapter pattern and consolidate servic…
lapidix Jun 23, 2025
eb1c9db
:truck: rename userApi to userAdapter for consistent naming convention
lapidix Jun 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Deploy to GitHub Pages
on:
push:
branches:
- main

permissions:
contents: read
pages: write
id-token: write

jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: latest

- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: "20"
cache: "pnpm"

- name: Install dependencies
run: pnpm install

- name: Build with Vite
run: pnpm run build

- name: Create 404 page
run: cp dist/index.html dist/404.html

- name: Disable Jekyll
run: touch dist/.nojekyll

- name: Setup Pages
uses: actions/configure-pages@v4

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: "./dist"

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
"coverage": "vitest run --coverage"
},
"dependencies": {
"@tanstack/react-query": "^5.74.7",
"react": "^19.1.0",
"react-dom": "^19.1.0"
"react-dom": "^19.1.0",
"zustand": "^5.0.3"
},
"devDependencies": {
"@eslint/js": "^9.25.1",
Expand Down
46 changes: 45 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 0 additions & 20 deletions src/App.tsx

This file was deleted.

25 changes: 25 additions & 0 deletions src/app/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { PostsManagerPage } from "@/pages/posts/manager"

import { Footer } from "@/widgets/common/footer"
import { Header } from "@/widgets/common/header"
import { BrowserRouter as Router } from "react-router-dom"
import { TanstackQueryProvider } from "./provider/tanstack-query"
import "./styles/index.css"

const App = () => {
return (
<TanstackQueryProvider>
<Router>
<div className="flex flex-col min-h-screen">
<Header />
<main className="flex-grow container mx-auto px-4 py-8">
<PostsManagerPage />
</main>
<Footer />
</div>
</Router>
</TanstackQueryProvider>
)
}

export default App
1 change: 0 additions & 1 deletion src/app/assets/react.svg

This file was deleted.

1 change: 1 addition & 0 deletions src/app/provider/tanstack-query/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { TanstackQueryProvider } from "./tanstack-query-provider";
7 changes: 7 additions & 0 deletions src/app/provider/tanstack-query/tanstack-query-provider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { queryClient } from "@/shared/api"
import { QueryClientProvider } from "@tanstack/react-query"
import * as React from "react"

export const TanstackQueryProvider = ({ children }: { children: React.ReactNode }) => {
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
}
File renamed without changes.
3 changes: 3 additions & 0 deletions src/entities/comment/api/comment-query-key.api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const COMMENT_QUERY_KEY = {
byPostId: (postId: number) => ["comments", postId] as const,
}
52 changes: 52 additions & 0 deletions src/entities/comment/api/comment.api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { ApiClient } from "@/shared/api/api"
import { ApiResponse } from "@/shared/types"
import { CommentResponseDto } from "../dto/comment.dto"
import { Comment } from "../types"

export const commentApi = (apiClient: ApiClient) => ({
listByPost: async (postId: number): Promise<CommentResponseDto> => {
return await apiClient
.get<ApiResponse<CommentResponseDto>>(`/comments/post/${postId}`)
.then((response) => response.data)
.catch((error) => {
console.error("Comments List Error: ", error)
return error
})
},
create: async (body: string, postId: number, userId: number): Promise<Comment> => {
return await apiClient
.post<ApiResponse<Comment>>(`/comments/add`, { body, postId, userId })
.then((response) => response.data)
.catch((error) => {
console.error("Comment Create Error: ", error)
return error
})
},
update: async (id: number, body: string): Promise<Comment> => {
return await apiClient
.put<ApiResponse<Comment>>(`/comments/${id}`, { body })
.then((response) => response.data)
.catch((error) => {
console.error("Comment Update Error: ", error)
return error
})
},
remove: async (id: number): Promise<boolean> => {
return await apiClient
.delete<ApiResponse<void>>(`/comments/${id}`)
.then((response) => response.ok)
.catch((error) => {
console.error("Comment Remove Error: ", error)
return error
})
},
likeComment: async (id: number): Promise<boolean> => {
return await apiClient
.patch<ApiResponse<void>>(`/comments/${id}/like`)
.then((response) => response.ok)
.catch((error) => {
console.error("Comment Like Error: ", error)
return error
})
},
})
2 changes: 2 additions & 0 deletions src/entities/comment/api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { COMMENT_QUERY_KEY } from "./comment-query-key.api"
export { commentApi } from "./comment.api"
6 changes: 6 additions & 0 deletions src/entities/comment/dto/comment.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Pagination } from "@/shared/types"
import { Comment } from "../types/comment.types"

export interface CommentResponseDto extends Pagination {
comments: Comment[]
}
25 changes: 25 additions & 0 deletions src/entities/comment/stores/comment.store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { create } from "zustand"
import { Comment } from "../types"

type CommentStoreState = Pick<Comment, "body" | "postId" | "id"> & {
userId: number

setBody: (body: string) => void
setPostId: (postId: number) => void
setUserId: (userId: number) => void
setSelectedComment: (postId: number, commentId: number, body: string) => void
reset: () => void
}

export const useCommentStore = create<CommentStoreState>((set) => ({
body: "",
postId: 0,
userId: 0,
id: 0,

setBody: (body) => set({ body }),
setPostId: (postId) => set({ postId }),
setUserId: (userId) => set({ userId }),
setSelectedComment: (postId: number, commentId: number, body: string) => set({ postId, id: commentId, body }),
reset: () => set({ body: "", postId: 0 }),
}))
22 changes: 22 additions & 0 deletions src/entities/comment/stores/comments.stores.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { create } from "zustand"
import { Comment } from "../types"

interface CommentsState {
comments: Array<Comment>
setComments: (comments: Comment[]) => void
addComment: (comment: Comment) => void
removeComment: (id: number) => void
updateComment: (comment: Comment) => void
}

export const commentsStore = () => {
return create<CommentsState>((set) => ({
comments: [],
setComments: (comments: Comment[]) => set({ comments }),
addComment: (comment: Comment) => set((state) => ({ comments: [...state.comments, comment] })),
removeComment: (id: number) =>
set((state) => ({ comments: state.comments.filter((comment) => comment.id !== id) })),
updateComment: (comment: Comment) =>
set((state) => ({ comments: state.comments.map((c) => (c.id === comment.id ? comment : c)) })),
}))
}
1 change: 1 addition & 0 deletions src/entities/comment/stores/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { useCommentStore } from "./comment.store"
9 changes: 9 additions & 0 deletions src/entities/comment/types/comment.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { User } from "@/entities/user/types/user.types"

export interface Comment {
body: string
id: number
likes: number
postId: number
user: User
}
1 change: 1 addition & 0 deletions src/entities/comment/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { type Comment } from "./comment.types"
18 changes: 18 additions & 0 deletions src/entities/comment/ui/comment-view/CommentView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { HighlightText } from "@/shared/ui"
import { Comment } from "../../types"

interface CommentViewProps extends React.HTMLAttributes<HTMLDivElement> {
comment: Comment
searchQuery: string
}

export const CommentView: React.FC<CommentViewProps> = ({ comment, searchQuery, ...props }) => {
return (
<div {...props} className="flex items-center space-x-2 overflow-hidden">
<span className="font-medium truncate">{comment.user.username}:</span>
<span className="truncate">
<HighlightText text={comment.body} highlight={searchQuery} />
</span>
</div>
)
}
1 change: 1 addition & 0 deletions src/entities/comment/ui/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { CommentView } from "./comment-view/CommentView"
2 changes: 2 additions & 0 deletions src/entities/post/api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { POST_QUERY_KEY } from "./post-query-key.api"
export { postApi } from "./post.api"
7 changes: 7 additions & 0 deletions src/entities/post/api/post-query-key.api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const POST_QUERY_KEY = {
all: ["posts"] as const,
list: (params: { limit?: number; skip?: number }) => ["posts", "list", params] as const,
search: (query: string) => ["posts", "search", query] as const,
tag: (tag: string) => ["posts", "tag", tag] as const,
detail: (id: number) => ["post", id] as const,
}
Loading