Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge to main for v1.0.2 #392

Merged
merged 41 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
ad3ffb6
refactor: #381 space type submit μΆ”κ°€
donghunee Sep 12, 2024
4e7a4d5
feat: #381 imageUpload api hook μΆ”κ°€
donghunee Sep 12, 2024
30ac14c
refactor: #381 νŒ€μ› -> μΈμ›μœΌλ‘œ λ³€κ²½
donghunee Sep 12, 2024
6d7a1f4
refactor: #381 μΉ΄μΉ΄μ˜€ν†‘ μ΄ˆλŒ€ν•˜κΈ° 문ꡬ μˆ˜μ •
donghunee Sep 12, 2024
a70936c
refactor: #381 image upload pending 적용
donghunee Sep 12, 2024
fc1a08d
refactor: #381 ν•„μš”μ—†λŠ” λ³€μˆ˜ 제거
donghunee Sep 12, 2024
c1c5532
refactor: #381 ν•¨μˆ˜ ꡬ쑰 λ³€κ²½
donghunee Sep 12, 2024
40db547
refactor: #381 링크 볡사 메세지 μˆ˜μ •
donghunee Sep 12, 2024
67a9b0a
refactor: #381 슀페이슀 이름 적용
donghunee Sep 12, 2024
f84c11c
Merge pull request #382 from depromeet/refactor/381/invite-member
donghunee Sep 12, 2024
5b93014
refactor: #381 μ΄ˆλŒ€ 문ꡬ μˆ˜μ •
donghunee Sep 12, 2024
42c66a5
Merge pull request #383 from depromeet/refactor/381/invite-member
donghunee Sep 12, 2024
f187dd5
refactor: #381 μ μ ˆν•œ 쑰사 λ„£μ–΄μ£ΌλŠ” ν•¨μˆ˜ 적용
donghunee Sep 12, 2024
12cb5b1
refactor: #381 쑰사 ν•¨μˆ˜ 둜직 λ³€κ²½
donghunee Sep 12, 2024
28fe151
Merge pull request #384 from depromeet/refactor/381/invite-member
donghunee Sep 12, 2024
55f68c4
feat: #339 UI 변경사항 μ™„λ£Œ API μ—°κ²° μ „
sean2337 Sep 9, 2024
a6c6dd7
feat: #339 UI 변경사항에 λ”°λ₯Έ 회고 κ΄€λ ¨ νƒ€μž… λ³€κ²½
sean2337 Sep 9, 2024
ed201ec
feat: #339 회고 μƒνƒœμ— λ”°λ₯Έ 마감일 UI 반영
sean2337 Sep 9, 2024
331a2e2
chore: 병합 κ³Όμ • 이슈 컀밋
sean2337 Sep 12, 2024
6ad2efe
feat: 339 회고둝 λ”λ―Έλ°μ΄ν„°μ—μ„œ API μ—°κ²°
sean2337 Sep 12, 2024
e244c11
feat: 339 뢄석 Empty μ˜ˆμ™Έ 처리 진행
sean2337 Sep 12, 2024
454cd1c
feat: 339 useApiGetAnalysis retry λΆ€μ—¬
sean2337 Sep 12, 2024
61e1bd8
feat: 339 useApiGetAnalysis retry 1둜 λΆ€μ—¬
sean2337 Sep 12, 2024
370d761
chore: #339 회고 뢄석 λΆˆκ°€ μ•ˆλ‚΄ ν…μŠ€νŠΈ λ³€κ²½
sean2337 Sep 12, 2024
f5fe08e
feat:#339 κ°œμΈμ •λ³΄μ²˜λ¦¬λ°©μΉ¨, μ„œλΉ„μŠ€ μ΄μš©μ•½κ°„ μΆ”κ°€
sean2337 Sep 12, 2024
af78370
feat:#339 κ°œμΈμ •λ³΄μ²˜λ¦¬λ°©μΉ¨, μ„œλΉ„μŠ€ μ΄μš©μ•½κ°„ 문ꡬ μ‚½μž…
sean2337 Sep 12, 2024
38412eb
feat: #339 κ°œμΈλΆ„μ„ ν•˜λ‚˜λΌλ„ μžˆμ„μ‹œ λ³΄μ—¬μ£Όκ²Œ λ³€κ²½
sean2337 Sep 12, 2024
79fc6b7
feat: #339 λͺ¨λ“  인원이 λ‹€ ν–ˆμ„λ•Œ 마감 ν•  수 있게 ν•œ λΆ€λΆ„ μ·¨μ†Œ
sean2337 Sep 12, 2024
b0667d8
feat: #339 아무도 쓰지 μ•Šκ³  마감 μ‹œ 뢄석 데이터 계속 λΆ€λ₯΄λŠ” λΆ€λΆ„ κ°œμ„ 
sean2337 Sep 12, 2024
5fa72f0
refactor: #339 회고둝 μ»΄ν¬λ„ŒνŠΈ ν΄λ¦­ν•¨μˆ˜ λ¦¬νŒ©ν† λ§
sean2337 Sep 12, 2024
fc08588
chore: #339 Date ν•¨μˆ˜μ˜ νƒ€μž… 처리 진행
sean2337 Sep 12, 2024
db84f14
Merge pull request #385 from depromeet/feat/339/qaSpaceDetailView
sean2337 Sep 13, 2024
0b267e3
feat: #386 Readme.md 파일 생성
sean2337 Sep 13, 2024
3ae1b93
feat: #388 Rename SaveText
sean2337 Sep 13, 2024
f4f6bc6
Merge pull request #389 from depromeet/feat/388/renameSave
sean2337 Sep 13, 2024
8fbb960
feat: #386 Readme.md 파일 μˆ˜μ •
sean2337 Sep 13, 2024
2a1cdbd
feat: #386 Readme.md 파일 이미지 μˆ˜μ •
sean2337 Sep 13, 2024
a25301b
feat: #386 hits μ—°κ²° μ»΄ν¬λ„ŒνŠΈ μΆ”κ°€
sean2337 Sep 13, 2024
6fb120a
feat: #386 markλ₯Ό ν†΅ν•œ μ€‘μš” 포인트 밑쀄
sean2337 Sep 13, 2024
82e9155
feat: #386 사진 κΈ€ μœ„μΉ˜ λ³€κ²½
sean2337 Sep 13, 2024
0bb2b9e
Merge pull request #387 from depromeet/feat/386/addReadme
sean2337 Sep 13, 2024
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
20 changes: 11 additions & 9 deletions apps/web/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import Cookies from "js-cookie";
/** API μ‚¬μš© μ „, ENV νŒŒμΌμ„ 톡해 μ„œλ²„ 연동 섀정을 ν•΄μ£Όμ„Έμš” */
const API_URL = import.meta.env.VITE_API_URL as string;

export type ErrorResponse = { name: string; message: string };

const baseApi = axios.create({
baseURL: API_URL,
timeout: 5000,
Expand All @@ -21,8 +23,8 @@ const logOnDev = (message: string) => {
};

/** API μš”μ²­μ΄ μ‹€νŒ¨ν•œ 경우 ν˜ΈμΆœλ˜λŠ” ν•¨μˆ˜ */
const onError = (status: number, message: string) => {
const error = { status, message };
const onError = (status: number, message: string, data?: ErrorResponse) => {
const error = { status, message, data };
throw error;
};

Expand Down Expand Up @@ -64,32 +66,32 @@ const onErrorResponse = (error: AxiosError | Error) => {
if (axios.isAxiosError(error)) {
const { message } = error;
const { method, url } = error?.config as AxiosRequestConfig;
const { status, statusText } = error?.response as AxiosResponse;
const { status, statusText, data } = error?.response as AxiosResponse<ErrorResponse>;

logOnDev(`[API ERROR_RESPONSE ${status} | ${statusText} | ${message}] ${method?.toUpperCase()} ${url}`);

switch (status) {
case 400:
onError(status, "잘λͺ»λœ μš”μ²­μ„ ν–ˆμ–΄μš”");
onError(status, "잘λͺ»λœ μš”μ²­μ„ ν–ˆμ–΄μš”", data);
break;
case 401: {
onError(status, "인증을 μ‹€νŒ¨ν–ˆμ–΄μš”");
onError(status, "인증을 μ‹€νŒ¨ν–ˆμ–΄μš”", data);
break;
}
case 403: {
onError(status, "κΆŒν•œμ΄ μ—†λŠ” μƒνƒœλ‘œ μ ‘κ·Όν–ˆμ–΄μš”");
onError(status, "κΆŒν•œμ΄ μ—†λŠ” μƒνƒœλ‘œ μ ‘κ·Όν–ˆμ–΄μš”", data);
break;
}
case 404: {
onError(status, "찾을 수 μ—†λŠ” νŽ˜μ΄μ§€λ₯Ό μš”μ²­ν–ˆμ–΄μš”");
onError(status, "찾을 수 μ—†λŠ” νŽ˜μ΄μ§€λ₯Ό μš”μ²­ν–ˆμ–΄μš”", data);
break;
}
case 500: {
onError(status, "μ„œλ²„ 였λ₯˜κ°€ λ°œμƒν–ˆμ–΄μš”");
onError(status, "μ„œλ²„ 였λ₯˜κ°€ λ°œμƒν–ˆμ–΄μš”", data);
break;
}
default: {
onError(status, `기타 μ—λŸ¬κ°€ λ°œμƒν–ˆμ–΄μš” : ${error?.message}`);
onError(status, `기타 μ—λŸ¬κ°€ λ°œμƒν–ˆμ–΄μš” : ${error?.message}`, data);
}
}
} else if (error instanceof Error && error?.name === "TimoutError") {
Expand Down
14 changes: 13 additions & 1 deletion apps/web/src/app/info/PrivacyPolicyPage.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
import { css } from "@emotion/react";

import { Typography } from "@/component/common/typography";
import { info } from "@/config/info";
import { DefaultLayout } from "@/layout/DefaultLayout";

export function PrivacyPolicyPage() {
return (
<DefaultLayout title="κ°œμΈμ •λ³΄ 처리방침">
<Typography variant="body16Medium">{info.privacyPolicy}</Typography>
<Typography variant="body16Medium">
<pre
css={css`
white-space: pre-wrap;
word-wrap: break-word;
overflow-wrap: break-word;
`}
>
{info.privacyPolicy}
</pre>
</Typography>
</DefaultLayout>
);
}
14 changes: 13 additions & 1 deletion apps/web/src/app/info/TermsOfServicePage.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
import { css } from "@emotion/react";

import { Typography } from "@/component/common/typography";
import { info } from "@/config/info";
import { DefaultLayout } from "@/layout/DefaultLayout";

export function TermsOfServicePage() {
return (
<DefaultLayout title="μ΄μš©μ•½κ΄€">
<Typography variant="body16Medium">{info.termsOfService}</Typography>
<Typography variant="body16Medium">
<pre
css={css`
white-space: pre-wrap;
word-wrap: break-word;
overflow-wrap: break-word;
`}
>
{info.termsOfService}
</pre>
</Typography>
</DefaultLayout>
);
}
20 changes: 14 additions & 6 deletions apps/web/src/app/retrospect/analysis/RetrospectAnalysisPage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Fragment } from "react";
import { Fragment, useEffect } from "react";
import { useLocation } from "react-router-dom";

import { LoadingModal } from "@/component/common/Modal/LoadingModal.tsx";
Expand All @@ -10,9 +10,10 @@ import { QuestionForm } from "@/component/retrospect/analysis/QuestionForm.tsx";
import { useGetAnalysisAnswer } from "@/hooks/api/retrospect/analysis/useGetAnalysisAnswer.ts";
import { useTabs } from "@/hooks/useTabs";
import { DualToneLayout } from "@/layout/DualToneLayout";
import { EmptyList } from "@/component/common/empty";

export const RetrospectAnalysisPage = () => {
const { title } = useLocation().state as { title: string };
const { title, defaultTab } = useLocation().state as { title: string; defaultTab: "질문" | "κ°œλ³„" | "뢄석" };

const tabMappings = {
질문: "QUESTIONS",
Expand All @@ -27,6 +28,11 @@ export const RetrospectAnalysisPage = () => {
const spaceId = queryParams.get("spaceId");
const retrospectId = queryParams.get("retrospectId");
const { data, isLoading } = useGetAnalysisAnswer({ spaceId: spaceId!, retrospectId: retrospectId! });
useEffect(() => {
if (defaultTab) {
selectTab(defaultTab);
}
}, []);
return (
<DualToneLayout
bottomTheme="gray"
Expand All @@ -38,13 +44,15 @@ export const RetrospectAnalysisPage = () => {
}
>
{isLoading && <LoadingModal />}
{
{!data || data.individuals.length === 0 ? (
<EmptyList icon={"ic_clock"} message={"제좜된 νšŒκ³ κ°€ μ—†μ–΄μš”"} />
) : (
{
QUESTIONS: <QuestionForm data={data!} />,
INDIVIDUAL_ANALYSIS: <PersonalForm data={data!} />,
QUESTIONS: <QuestionForm data={data} />,
INDIVIDUAL_ANALYSIS: <PersonalForm data={data} />,
ANALYSIS: <AnalysisContainer spaceId={spaceId!} retrospectId={retrospectId!} hasAIAnalyzed={data?.hasAIAnalyzed} />,
}[selectedTab]
}
)}
</DualToneLayout>
);
};
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
import { useLocation } from "react-router-dom";

import { Header } from "@/component/common/header";
import { LoadingModal } from "@/component/common/Modal/LoadingModal";
import { Spacing } from "@/component/common/Spacing";
import { CardCarousel } from "@/component/retrospect/template/card/CardCarousel";
import { TemplateKey } from "@/component/retrospect/template/card/template.const";
import { useApiGetSpace } from "@/hooks/api/space/useApiGetSpace";
import { DefaultLayout } from "@/layout/DefaultLayout";
import { chooseParticle } from "@/utils/retrospect/chooseParticle";
import { createTemplateArr } from "@/utils/retrospect/createTemplateArr";

export function RecommendSearch() {
const { templateId, spaceId } = useLocation().state as { templateId: string; spaceId: string };
const TemplateArr = createTemplateArr(templateId as unknown as TemplateKey);
const { data, isLoading } = useApiGetSpace(spaceId);

if (isLoading) return <LoadingModal />;

const particle = chooseParticle(data?.name ?? "");

return (
<DefaultLayout theme="gray">
<Header title={`λ””ν”„λ§Œκ³Ό μ–΄μšΈλ¦¬λŠ”\n회고 ν…œν”Œλ¦Ώμ„ μ°ΎλŠ”μ€‘...`} />
<Header title={`${data?.name}${particle} μ–΄μšΈλ¦¬λŠ”\n회고 ν…œν”Œλ¦Ώμ„ μ°ΎλŠ”μ€‘...`} />
<Spacing size={13} />
<div>
<CardCarousel templateId={templateId} spaceId={spaceId} templateArr={TemplateArr} />
Expand Down
17 changes: 10 additions & 7 deletions apps/web/src/app/space/CreateDonePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useLocation, useNavigate } from "react-router-dom";
import CreateDone from "@/assets/lottie/space/create_done.json";
import { ButtonProvider, IconButton } from "@/component/common/button";
import { Icon } from "@/component/common/Icon";
import { LoadingModal } from "@/component/common/Modal/LoadingModal";
import { Spacing } from "@/component/common/Spacing";
import { Typography } from "@/component/common/typography";
import { useApiGetUser } from "@/hooks/api/auth/useApiGetUser";
Expand All @@ -20,7 +21,7 @@ import { encryptId } from "@/utils/space/cryptoKey";
export function CreateDonePage() {
const navigate = useNavigate();
const { spaceId } = useLocation().state as { spaceId: string };
const { data: spaceData } = useApiGetSpace(spaceId);
const { data: spaceData, isLoading } = useApiGetSpace(spaceId);
const [animate, setAnimate] = useState(spaceData?.category === ProjectType.Individual);
const { data: userData } = useApiGetUser();
const { toast } = useToast();
Expand All @@ -41,8 +42,8 @@ export function CreateDonePage() {
if (bridge.isWebViewBridgeAvailable) {
await bridge.sendShareToKakao({
content: {
title: `${userData.name}λ‹˜μ΄ μŠ€νŽ˜μ΄μŠ€μ— μ΄ˆλŒ€ν–ˆμŠ΅λ‹ˆλ‹€.`,
description: "μ–΄μ„œμ˜€μ„Έμš©~!!",
title: `${userData.name}λ‹˜μ˜ 회고 μ΄ˆλŒ€μž₯`,
description: `ν•¨κ»˜ νšŒκ³ ν•΄μš”! ${userData.name}λ‹˜μ΄ νŒ€ λ ˆμ΄μ–΄ μŠ€νŽ˜μ΄μŠ€μ— μ΄ˆλŒ€ν–ˆμ–΄μš”`,
imageUrl: "https://kr.object.ncloudstorage.com/layer-bucket/small_banner.png",
link: {
mobileWebUrl: `${window.location.protocol}//${window.location.host}/space/join/${encryptedId}`,
Expand All @@ -62,21 +63,23 @@ export function CreateDonePage() {
} else {
shareKakaoWeb(
`${window.location.protocol}//${window.location.host}/space/join/${encryptedId}`,
`${userData.name}λ‹˜μ΄ μŠ€νŽ˜μ΄μŠ€μ— μ΄ˆλŒ€ν–ˆμŠ΅λ‹ˆλ‹€.`,
"μ–΄μ„œμ˜€μ„Έμš©~!!",
`${userData.name}λ‹˜μ˜ 회고 μ΄ˆλŒ€μž₯`,
`ν•¨κ»˜ νšŒκ³ ν•΄μš”! ${userData.name}λ‹˜μ΄ ${spaceData?.name} μŠ€νŽ˜μ΄μŠ€μ— μ΄ˆλŒ€ν–ˆμ–΄μš”`,
);
}
};

const handleCopyClipBoard = async () => {
try {
await navigator.clipboard.writeText(`${window.location.protocol}//${window.location.host}/space/join/${encryptedId}`);
toast.success("볡사 성곡!!");
toast.success("링크 볡사가 μ™„λ£Œλ˜μ—ˆμ–΄μš”!");
} catch (e) {
alert("failed");
alert("링크 볡사에 μ‹€νŒ¨ν–ˆμ–΄μš”!");
}
};

if (isLoading) return <LoadingModal />;

return (
<>
{spaceData && (
Expand Down
60 changes: 32 additions & 28 deletions apps/web/src/app/space/SpaceViewPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { css } from "@emotion/react";
import { PATHS } from "@layer/shared";
import { useQueries } from "@tanstack/react-query";
import Cookies from "js-cookie";
import { Fragment, useEffect, useState } from "react";
import { Fragment, useEffect, useRef, useState } from "react";
import { useNavigate } from "react-router-dom";

import { BottomSheet } from "@/component/BottomSheet";
Expand All @@ -22,12 +22,16 @@ import { useApiOptionsGetSpaceInfo } from "@/hooks/api/space/useApiOptionsGetSpa
import { useBottomSheet } from "@/hooks/useBottomSheet";
import { useModal } from "@/hooks/useModal";
import { useRequiredParams } from "@/hooks/useRequiredParams";
import { DualToneLayout } from "@/layout/DualToneLayout";
import { DefaultLayout } from "@/layout/DefaultLayout";
import { useTestNatigate } from "@/lib/test-natigate";
import { DESIGN_TOKEN_COLOR } from "@/style/designTokens";
import { Retrospect } from "@/types/retrospect";
import { useCollisionDetection } from "@/hooks/useCollisionDetection";

export function SpaceViewPage() {
const appbarRef = useRef<HTMLDivElement>(null);
const contentRef = useRef<HTMLDivElement>(null);
const isColliding = useCollisionDetection(appbarRef, contentRef);
const navigate = useNavigate();
const appNavigate = useTestNatigate();
const memberId = Cookies.get("memberId");
Expand Down Expand Up @@ -99,32 +103,20 @@ export function SpaceViewPage() {
}

return (
<DualToneLayout
topTheme="dark"
<DefaultLayout
theme={isColliding ? "default" : "dark"}
LeftComp={
<Icon
size={2.4}
icon="ic_arrow_left"
css={css`
cursor: pointer;
`}
onClick={() => appNavigate(PATHS.home())}
color={DESIGN_TOKEN_COLOR.gray00}
/>
}
TopComp={
<>
<ActionItemListView
restrospectArr={restrospectArr ? restrospectArr : []}
isPossibleMake={doneRetrospects.length === 0}
spaceId={spaceInfo?.id}
teamActionList={teamActionList?.teamActionItemList || []}
leaderId={spaceInfo?.leader.id}
<div ref={appbarRef}>
<Icon
size={2.4}
icon="ic_arrow_left"
css={css`
cursor: pointer;
`}
onClick={() => appNavigate(PATHS.home())}
color={DESIGN_TOKEN_COLOR.gray00}
/>
<Spacing size={1.1} />
<SpaceCountView mainTemplate={spaceInfo?.formTag} memberCount={spaceInfo?.memberCount} isLeader={isLeader} />
<Spacing size={2.4} />
</>
</div>
}
title={spaceInfo?.name}
RightComp={
Expand Down Expand Up @@ -154,6 +146,18 @@ export function SpaceViewPage() {
/>
}
>
<div ref={contentRef}>
<ActionItemListView
restrospectArr={restrospectArr ? restrospectArr : []}
isPossibleMake={doneRetrospects.length === 0}
spaceId={spaceInfo?.id}
teamActionList={teamActionList?.teamActionItemList || []}
leaderId={spaceInfo?.leader.id}
/>
<Spacing size={1.1} />
<SpaceCountView mainTemplate={spaceInfo?.formTag} memberCount={spaceInfo?.memberCount} isLeader={isLeader} />
<Spacing size={2.4} />
</div>
<div
css={css`
width: calc(100% + 4rem);
Expand Down Expand Up @@ -210,7 +214,7 @@ export function SpaceViewPage() {
gap: 0.6rem;
`}
>
<Typography variant="title18Bold">μ™„λ£Œλœ 회고</Typography>
<Typography variant="title18Bold">마감된 회고</Typography>
<Typography variant="title16Bold" color="gray600">
{doneRetrospects?.length}
</Typography>
Expand Down Expand Up @@ -245,6 +249,6 @@ export function SpaceViewPage() {
handler={true}
/>
<Toast />
</DualToneLayout>
</DefaultLayout>
);
}
6 changes: 5 additions & 1 deletion apps/web/src/component/common/empty/EmptyList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ import { IconType } from "@/component/common/Icon/Icon";
import { Typography } from "@/component/common/typography";

type EmptyListProps = {
title?: React.ReactNode;
message: React.ReactNode;
icon: IconType;
iconSize?: number;
} & React.HTMLAttributes<HTMLDivElement>;

export function EmptyList({ message, icon, iconSize = 7.2, children, ...props }: PropsWithChildren<EmptyListProps>) {
export function EmptyList({ title, message, icon, iconSize = 7.2, children, ...props }: PropsWithChildren<EmptyListProps>) {
return (
<div
css={css`
Expand All @@ -25,6 +26,9 @@ export function EmptyList({ message, icon, iconSize = 7.2, children, ...props }:
{...props}
>
<Icon icon={icon} size={iconSize} />
<Typography variant="title18Bold" color={"gray900"}>
{title}
</Typography>
<div
css={css`
text-align: center;
Expand Down
Loading
Loading