Skip to content

Commit

Permalink
[RELEASE] release 2.2 게스트 모드 추가 & 슬랙 메시지 (v2.2)
Browse files Browse the repository at this point in the history
v2.2 배포

**[업데이트 내용]**
- 게스트모드가 추가됩니다. (#9 #18 #23)
  - 기존 로그인을 해야 사용할 수 있던 서비스를 로그인 없이 게스트모드로 이용 가능합니다. 
    - /main, /detail/[] 페이지를 이용 가능하며, 참여 목록은 블라인드 처리되어 볼 수 없습니다. 


-  주간발표 한정으로 슬랙 메시지를 보낼 수 있습니다. (#15)
    - 행사 카테고리를 주간발표로 하여 게시글을 올리면 prompt창이 뜨며, 선택 여부에 따라서 메시지를 보낼 수 있습니다.
  • Loading branch information
geongyu09 authored May 3, 2024
2 parents 89459fc + 483ca43 commit 9c16b7e
Show file tree
Hide file tree
Showing 44 changed files with 585 additions and 82 deletions.
17 changes: 8 additions & 9 deletions FE/next.config.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
// rewrite
async redirects() {
return [
{
source: "/",
destination: "/main",
permanent: true,
},
];
},
// async rewrites() {
// return [
// {
// source: "/main",
// destination: "/",
// },
// ];
// },
};

module.exports = nextConfig;
1 change: 1 addition & 0 deletions FE/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
},
"dependencies": {
"@tanstack/react-query": "^4.35.7",
"@tanstack/react-query-devtools": "^5.28.14",
"@types/qs": "^6.9.10",
"@types/react-syntax-highlighter": "^15.5.11",
"axios": "^1.6.2",
Expand Down
18 changes: 18 additions & 0 deletions FE/pnpm-lock.yaml

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

9 changes: 9 additions & 0 deletions FE/public/icons/blackCompany.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions FE/src/apis/instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const https = axios.create({

https.interceptors.request.use(
async (config) => {
if (typeof window === "undefined") return config;
const accessToken = localStorage.getItem("accessToken")?.replace(/"/g, "");
const tokenExpiration = localStorage.getItem("tokenExpiration");

Expand Down
37 changes: 35 additions & 2 deletions FE/src/apis/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,13 @@ import MESSAGE from "@/constants/MESSAGE";

export const getProgramById = async (
programId: number,
isLoggedIn: boolean,
): Promise<ProgramInfoDto> => {
const url = isLoggedIn
? API.PROGRAM.DETAIL(programId)
: API.PROGRAM.GUEST_DETAIL(programId);
const { data } = await https({
url: API.PROGRAM.DETAIL(programId),
url,
});
return new ProgramInfoDto(data?.data);
};
Expand All @@ -37,16 +41,19 @@ export interface GetProgramListRequest {
programStatus: ProgramStatus;
size: number;
page: number;
isLoggedIn: boolean;
}

export const getProgramList = async ({
category,
programStatus,
size,
page,
isLoggedIn,
}: GetProgramListRequest): Promise<ProgramListDto> => {
const url = isLoggedIn ? API.PROGRAM.LIST : API.PROGRAM.GUEST_LIST;
const { data } = await https({
url: API.PROGRAM.LIST,
url,
method: "GET",
params: {
category,
Expand Down Expand Up @@ -86,6 +93,32 @@ export interface PostProgramRequest
members: { memberId: number }[];
}

export const sendSlackMessage = async (
programId: number,
isRetry: boolean = false,
) => {
if (!window) return;

if (!isRetry) {
const isConfirmed = confirm(MESSAGE.SLACK_MESSAGE.CONFIRM);
if (!isConfirmed) return;
}

return await https({
url: API.PROGRAM.SEND_MESSAGE(programId),
method: "POST",
data: {
programUrl:
process.env.NEXT_PUBLIC_SLACK_MESSAGE_REQUEST_URL_PREFIX + programId,
},
})
.then(() => alert(MESSAGE.SLACK_MESSAGE.SUCCESS))
.catch(() => {
const retry = confirm(MESSAGE.SLACK_MESSAGE.FAIL);
if (retry) sendSlackMessage(programId);
});
};

export const postProgram = async (
body: PostProgramRequest,
): Promise<ProgramIdDto> => {
Expand Down
2 changes: 2 additions & 0 deletions FE/src/app/(auth)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { PropsWithChildren } from "react";
import AuthValidate from "@/components/common/validate/Auth";

export default function AuthLayout({ children }: PropsWithChildren) {
return (
<main className="mb-28 mt-16 h-full w-full max-w-[500px] sm:max-w-[800px] lg:max-w-[1112px]">
<AuthValidate isHaveToLoggedInRoute={false} />
{children}
</main>
);
Expand Down
22 changes: 22 additions & 0 deletions FE/src/app/(guest)/guest/detail/[programId]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import AttendeeInfoContainer from "@/components/programDetail/attendee/AttendeeInfo.container";
import ProgramInfo from "@/components/programDetail/program/ProgramInfo";
import UserAttendModalContainer from "@/components/programDetail/userAttendModal/UserAttendModal.container";

interface ProgramDetailPageProps {
params: {
programId: string;
};
}

const ProgramDetailPage = ({ params }: ProgramDetailPageProps) => {
const { programId } = params;

return (
<div className="mb-16 space-y-16">
<ProgramInfo programId={+programId} isLoggedIn={false} />
<AttendeeInfoContainer programId={+programId} isLoggedIn={false} />
<UserAttendModalContainer programId={+programId} isLoggedIn={false} />
</div>
);
};
export default ProgramDetailPage;
19 changes: 19 additions & 0 deletions FE/src/app/(guest)/guest/detail/error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"use client";

import ErrorFallback from "@/components/common/ErrorFallback";

const DetailPageError = () => {
const error = {
message: "행사 정보를 불러오는 중에 오류가 발생했습니다.",
};

return (
<ErrorFallback
error={error}
resetErrorBoundary={() => {
window.location.reload();
}}
/>
);
};
export default DetailPageError;
4 changes: 4 additions & 0 deletions FE/src/app/(guest)/guest/detail/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import LoadingSpinner from "@/components/common/LoadingSpinner";

const DetailLoading = () => <LoadingSpinner />;
export default DetailLoading;
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { PropsWithChildren } from "react";
import Header from "@/components/common/header/Header";
import AuthValidate from "@/components/common/validate/Auth";

export default function ProgramLayout({ children }: PropsWithChildren) {
export default function GuestLayout({
children,
}: Readonly<{ children: React.ReactNode }>) {
return (
<>
<Header />
<AuthValidate isHaveToLoggedInRoute={false} />
<main className="my-16 w-full px-3 sm:max-w-[800px] lg:max-w-[1112px]">
{children}
</main>
Expand Down
6 changes: 6 additions & 0 deletions FE/src/app/(guest)/guest/main/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import LoadingSpinner from "@/components/common/LoadingSpinner";

const MainLoading = () => {
return <LoadingSpinner />;
};
export default MainLoading;
98 changes: 98 additions & 0 deletions FE/src/app/(guest)/guest/main/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// TODO: 서버 컴포넌트로 변경하기
"use client";

import { useSearchParams } from "next/navigation";
import { Suspense, useEffect, useState } from "react";
import { ErrorBoundary } from "react-error-boundary";
import ErrorFallback from "@/components/common/ErrorFallback";
import Tab from "@/components/common/tabs/Tab";
import TextTab from "@/components/common/tabs/TextTab";
import ProgramList from "@/components/main/ProgramList";
import ProgramListLoader from "@/components/main/ProgramList.loader";
import TeamBuildingDropup from "@/components/main/TeamBuildingDropup";
import MAIN from "@/constants/MAIN";
import PROGRAM from "@/constants/PROGRAM";
import { ProgramCategoryWithAll, ProgramStatus } from "@/types/program";

const MainPage = () => {
const searchParams = useSearchParams();

// TODO: Hook으로 변경하기
const [queryValue, setQueryValue] = useState(MAIN.DEFAULT_QUERY);

// TODO: useEffect를 Hook으로 변경하기
useEffect(() => {
setQueryValue({
...MAIN.DEFAULT_QUERY,
category:
(searchParams.get("category") as ProgramCategoryWithAll) ?? "all",
status: (searchParams.get("status") as ProgramStatus) ?? "active",
page: searchParams.get("page") ?? "1",
});
}, [searchParams]);

useEffect(() => {
window.history.replaceState(
{},
"",
`?category=${queryValue.category}&status=${queryValue.status}&page=${queryValue.page}`,
);
}, [queryValue]);

const handleSetCategory = (category: ProgramCategoryWithAll) => {
setQueryValue({
...queryValue,
category,
page: "1",
});
};

const handleSetStatus = (status: ProgramStatus) => {
setQueryValue({
...queryValue,
status,
page: "1",
});
};

const handleSetPage = (page: number) => {
setQueryValue({
...queryValue,
page: page.toString(),
});
};

// TODO: 합성 컴포넌트!
return (
<div className="relative space-y-8">
<Tab<ProgramCategoryWithAll>
options={Object.values(PROGRAM.CATEGORY_TAB_WITH_ALL)}
selected={queryValue.category}
onItemClick={(v) => handleSetCategory(v)}
size="lg"
baseColor="white"
pointColor="navy"
align="line"
/>
<TextTab<ProgramStatus>
options={Object.values(PROGRAM.STATUS_TAB)}
selected={queryValue.status}
onClick={(v) => handleSetStatus(v)}
/>
<ErrorBoundary FallbackComponent={ErrorFallback}>
<Suspense fallback={<ProgramListLoader />}>
<ProgramList
category={queryValue.category}
programStatus={queryValue.status}
page={+queryValue.page}
setPage={handleSetPage}
isLoggedIn={false}
/>
</Suspense>
</ErrorBoundary>
<TeamBuildingDropup />
</div>
);
};

export default MainPage;
6 changes: 3 additions & 3 deletions FE/src/app/(private)/(program)/detail/[programId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ const ProgramDetailPage = ({ params }: ProgramDetailPageProps) => {

return (
<div className="mb-16 space-y-16">
<ProgramInfo programId={+programId} />
<AttendeeInfoContainer programId={+programId} />
<UserAttendModalContainer programId={+programId} />
<ProgramInfo programId={+programId} isLoggedIn />
<AttendeeInfoContainer programId={+programId} isLoggedIn />
<UserAttendModalContainer programId={+programId} isLoggedIn />
</div>
);
};
Expand Down
2 changes: 1 addition & 1 deletion FE/src/app/(private)/(program)/edit/[programId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ interface ProgramEditPageProps {

const ProgramEditPage = ({ params }: ProgramEditPageProps) => {
const { programId } = params;
const { data: programInfo, isLoading } = useGetProgramById(+programId);
const { data: programInfo, isLoading } = useGetProgramById(+programId, true);

if (isLoading) return <LoadingSpinner />;

Expand Down
1 change: 1 addition & 0 deletions FE/src/app/(private)/(program)/main/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ const MainPage = () => {
programStatus={queryValue.status}
page={+queryValue.page}
setPage={handleSetPage}
isLoggedIn
/>
</Suspense>
</ErrorBoundary>
Expand Down
6 changes: 5 additions & 1 deletion FE/src/app/(private)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { PropsWithChildren } from "react";
import Header from "@/components/common/header/Header";
import AuthValidate from "@/components/common/validate/Auth";

const PrivateLayout = ({ children }: PropsWithChildren) => {
return (
<>
<AuthValidate />
{children}
<Header />
<main className="my-16 w-full px-3 sm:max-w-[800px] lg:max-w-[1112px]">
{children}
</main>
</>
);
};
Expand Down
3 changes: 3 additions & 0 deletions FE/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { redirect } from "next/navigation";

export default function Home() {
redirect("/login");
return (
<main>
<h1>Home</h1>
Expand Down
Loading

0 comments on commit 9c16b7e

Please sign in to comment.