Skip to content

Commit

Permalink
v1.0.1
Browse files Browse the repository at this point in the history
v1.0.1
  • Loading branch information
jwo0o0 authored Dec 18, 2024
2 parents 2afe4f9 + 3832d8c commit 6254282
Show file tree
Hide file tree
Showing 14 changed files with 455 additions and 96 deletions.
28 changes: 12 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
<div align=center>
<img src="https://github.com/jwo0o0/SNS_Project/blob/develop/public/images/og_image.png?raw=true" width="800" /><br/><br/>
<h1> 🗳️ PickIt </h2>
https://pickitsns.site/
<br><br>
<br>

[![Application](http://img.shields.io/badge/Application-000000?style=flat&logo=github&logoColor=white&link=https://pickitsns.site/)](https://sns.jwoo.site/)
[![Application](http://img.shields.io/badge/Application-000000?style=flat&logo=github&logoColor=white&link=https://pickitsns.site/)](https://pickitsns.site/)
<!--
[![Storybook](http://img.shields.io/badge/Storybook-FF4785?style=flat&logo=Storybook&logoColor=white&link=https://pickitsns.site)](https://sns.jwoo.site)
[![API Docs](http://img.shields.io/badge/Swagger-85EA2D?style=flat&logo=swagger&logoColor=white&link=https://pickitsns.site)](https://sns.jwoo.site)
Expand All @@ -26,14 +25,6 @@
3. **유용한 정보를 제공하는 효과적인 방식 제공**<br/>
SNS가 비즈니스와 지식 전달의 역할까지 하고 있습니다. 선택형 질문으로 자연스러운 참여를 유도하고, 기억에 더 남게 할 수 있습니다.

## 🔍 핵심 기능
#### 카카오 소셜 로그인
#### 피드 작성
#### 피드 조회
#### 팔로잉/팔로우
#### 실시간 채팅


## 🛠️ 기술 스택
### Client
![Next JS](https://img.shields.io/badge/Next.js-black?style=flat&logo=next.js&logoColor=white) ![TypeScript](https://img.shields.io/badge/typescript-%23007ACC.svg?style=flat&logo=typescript&logoColor=white) ![TailwindCSS](https://img.shields.io/badge/tailwindcss-%2338B2AC.svg?style=flat&logo=tailwind-css&logoColor=white) ![Tanstack Query](https://img.shields.io/badge/-Tanstack%20Query-FF4154?style=flat&logo=react%20query&logoColor=white) ![Zustand](https://img.shields.io/badge/Zustand-black?style=flat) ![PNPM](https://img.shields.io/badge/pnpm-%234a4a4a.svg?style=flat&logo=pnpm&logoColor=f69220) ![Zod](https://img.shields.io/badge/zod-%233068b7.svg?style=flat&logo=zod&logoColor=white)
Expand All @@ -45,12 +36,17 @@
![Amazon EC2](https://img.shields.io/badge/EC2-FF9900?style=flat&logo=amazonec2&logoColor=white) ![Amazon S3](https://img.shields.io/badge/S3-569A31?style=flat&logo=amazons3&logoColor=white) ![Amazon CodeDeploy](https://img.shields.io/badge/CodeDeploy-569A31?style=flat&logo=CodeDeploy&logoColor=white) ![Amazon Route 53](https://img.shields.io/badge/Route%2053-8C4FFF?style=flat&logo=amazonroute53&logoColor=white) ![Nginx](https://img.shields.io/badge/nginx-%23009639.svg?style=flat&logo=nginx&logoColor=white) ![GitHub Actions](https://img.shields.io/badge/github%20actions-%232671E5.svg?style=flat&logo=githubactions&logoColor=white)


## 🌐 서비스 아키텍처
<img src="https://github.com/user-attachments/assets/c8fd626a-7942-4f97-a5b6-25387f174b76" width="800" />
## 🔍 핵심 기능

## 📝 관련 기록
> - 블로그
![핵심기능1](https://github.com/user-attachments/assets/43f1398d-7c6f-46c0-bf82-2a5dfb2535da)

![핵심기능2](https://github.com/user-attachments/assets/9e466754-45dd-4a79-a9c5-26d29482000b)

### 🙋 만든 사람
![핵심기능3](https://github.com/user-attachments/assets/406ae775-db2c-4fcc-b714-a35eebaf81a2)

![핵심기능4](https://github.com/user-attachments/assets/26ad7109-9e4c-484b-9b51-39b000bdc4fb)


## 🌐 서비스 아키텍처
<img src="https://github.com/user-attachments/assets/c8fd626a-7942-4f97-a5b6-25387f174b76" width="800" />

2 changes: 2 additions & 0 deletions src/apis/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const AUTH_API = {
const IMAGE_API = {
PROFILE_UPLOAD: (userId: number) => `/image/profile?userId=${userId}`,
FEED_UPLOAD: (feedId: number) => `/image/feeds?feedId=${feedId}`,
FEED_UPDATE: (feedId: number) => `/image/feeds/${feedId}`,
};

const USER_API = {
Expand All @@ -23,6 +24,7 @@ const FEED_API = {
VOTE_FEED: (feedId: number) => `/feeds/${feedId}/vote`,
LIKE_FEED: (feedId: number) => `/feeds/${feedId}/like`,
DELETE_FEED: (feedId: number) => `/feeds/${feedId}`,
PATCH_FEED: (feedId: number) => `/feeds/${feedId}`,
GET_ALL_FEED: (page: number, limit: number) =>
`/feeds?page=${page}&limit=${limit}`,
GET_LIKED_FEED: (page: number, limit: number) =>
Expand Down
14 changes: 12 additions & 2 deletions src/components/common/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ const Dropdown = ({ handleClickDelete, hadleClickEdit }: DropdownProps) => {
</svg>
</DropdownMenuTrigger>
<DropdownMenuContent className="mr-4 md:mr-32 text-slate-900">
<DropdownMenuItem onClick={handleClickDelete}>
<DropdownMenuItem
onClick={(e) => {
e.stopPropagation();
handleClickDelete();
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
Expand All @@ -47,7 +52,12 @@ const Dropdown = ({ handleClickDelete, hadleClickEdit }: DropdownProps) => {
</svg>
삭제하기
</DropdownMenuItem>
<DropdownMenuItem onClick={hadleClickEdit}>
<DropdownMenuItem
onClick={(e) => {
e.stopPropagation();
hadleClickEdit();
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
Expand Down
49 changes: 44 additions & 5 deletions src/components/feed/Feed.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
"use client";
import { FC } from "react";
import { FC, useState } from "react";
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { ProfileImage } from "@/components/common/ProfileImage";
import { Modal, LoginModalContent } from "../common/modal";
import Dropdown from "@/components/common/Dropdown";
import { FeedEditDrawer } from "@/components/feed/FeedEditDrawer";

import { FeedType } from "@/lib/feed/feedTypes";
import { useQueryClient } from "@tanstack/react-query";
import feedKeys from "@/lib/feed/feedQueries";
import { useVoteFeed } from "@/lib/feed/hooks/useVoteFeed";
import { useLikeFeed } from "@/lib/feed/hooks/useLikeFeed";
import { useDeleteFeed } from "@/lib/feed/hooks/useDeleteFeed";
import { useLoginStatus } from "@/lib/auth/hooks/useLoginStatus";
import { useModalStore } from "@/store/modal/useModalStore";
import { useAuthStore } from "@/store/auth/useAuthStore";
import { useStore } from "@/store/useStore";
import timeAgo from "@/utils/format/timeAgo";
import getImageName from "@/utils/format/getImageName";

export interface FeedProps {
feedId: number;
data: FeedType | undefined;
data: FeedType;
handleVoteSuccess?: () => Promise<void>;
handleLikeSuccess?: () => Promise<void>;
}
Expand All @@ -29,9 +34,13 @@ export const Feed: FC<FeedProps> = ({
handleLikeSuccess,
}: FeedProps) => {
const router = useRouter();

const user = useStore(useAuthStore, (state) => state.user);
const { isLogin, isLoading } = useLoginStatus();
const openModal = useModalStore((state) => state.open);

const [isOpenDrawer, setIsOpenDrawer] = useState<boolean>(false);

const queryClient = useQueryClient();

const sum = data?.result.reduce((acc, cur) => acc + cur, 0) ?? 0;
Expand Down Expand Up @@ -85,6 +94,21 @@ export const Feed: FC<FeedProps> = ({
}
};

const { mutate: deleteFeedMutation } = useDeleteFeed();

const handleClickDelete = () => {
deleteFeedMutation(
{
feedId,
},
{
onSuccess: () => {
router.replace("/");
},
}
);
};

return (
<>
<div
Expand Down Expand Up @@ -188,9 +212,11 @@ export const Feed: FC<FeedProps> = ({
})}
</div>
)}
<div className="my-2 md:my-4 text-body2Normal">
{data?.pollContent}
</div>
{data?.isVoted && (
<div className="my-2 md:my-4 text-body2Normal">
{data?.pollContent}
</div>
)}
<div className="flex items-center text-slate-600">
<button
onClick={(e) => {
Expand Down Expand Up @@ -243,7 +269,20 @@ export const Feed: FC<FeedProps> = ({
<div className="text-sm">{data?.commentCount}</div>
</div>
</div>
{user?.id === data?.user.userId && (
<Dropdown
handleClickDelete={handleClickDelete}
hadleClickEdit={() => {
setIsOpenDrawer(true);
}}
/>
)}
</div>
<FeedEditDrawer
isOpen={isOpenDrawer}
setIsOpen={setIsOpenDrawer}
data={data}
/>
<Modal>
<LoginModalContent />
</Modal>
Expand Down
11 changes: 9 additions & 2 deletions src/components/feed/FeedContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@ import { useGetFeed } from "@/lib/feed/hooks/useGetFeed";
import { Feed } from "./Feed";

export const FeedContent = ({ feedId }: { feedId: number }) => {
const { data } = useGetFeed(feedId);
const { data, isError } = useGetFeed(feedId);

return <Feed feedId={feedId} data={data} />;
if (isError || !data) {
return <div>Failed to load feed.</div>;
}
return (
<>
<Feed feedId={feedId} data={data} />
</>
);
};
32 changes: 32 additions & 0 deletions src/components/feed/FeedEditDrawer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"use client";
import { Drawer, DrawerContent, DrawerTitle } from "@/components/ui/drawer";
import { FeedEditForm } from "@/components/feed/FeedEditForm";
import { FeedType } from "@/lib/feed/feedTypes";

interface FeedEditDrawerProps {
isOpen: boolean;
setIsOpen: (open: boolean) => void;
data: FeedType;
}
export const FeedEditDrawer = ({
isOpen,
setIsOpen,
data,
}: FeedEditDrawerProps) => {
return (
<>
<Drawer open={isOpen} onOpenChange={setIsOpen}>
<DrawerContent
aria-describedby={undefined}
className="mx-auto w-full md:w-[600px] lg:w-[680px] h-[80vh] bg-white z-50
px-4 py-2"
>
<DrawerTitle className="hidden"></DrawerTitle>
<div className="h-full overflow-y-scroll">
<FeedEditForm data={data} setIsOpen={setIsOpen} />
</div>
</DrawerContent>
</Drawer>
</>
);
};
Loading

0 comments on commit 6254282

Please sign in to comment.