Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions src/app/_components/SurveyScreen/ProgressBar.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
export default function ProgressBar({ progress }) {
return (
<div className="h-[12px] w-full bg-[#CFDAF2]">
<div className="h-2 w-full bg-[#CFDAF2]">
<div
className="h-[12px] rounded-lg bg-[#3560C0]"
className="h-2 rounded-lg bg-[#3560C0]"
style={{ width: `${progress}%` }}
></div>
</div>
Expand Down
13 changes: 6 additions & 7 deletions src/app/_components/SurveyScreen/SurveyOption.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,18 @@ export default function SurveyOption({
<div
onClick={onClick}
className={clsx(
"flex cursor-pointer items-center justify-between rounded-[12px] border-[2px] bg-[#F7F9FD] py-[16px] pr-[40px] pl-[24px]",
isSelected ? "border-[#577DD1]" : "border-[#F7F9FD]"
"flex cursor-pointer items-center justify-between rounded-xl border-2 py-4 pr-10 pl-6 transition-colors duration-100",
isSelected
? "border-[#577DD1] bg-[#F7F9FD]"
: "border-[#F6F7F8] bg-[#F6F7F8] text-[#B3B9C6] hover:bg-[#F7F9FD] hover:text-[#3560C0]"
)}
>
<p
className={clsx(
"text-body-large",
isSelected ? "text-[#3560C0]" : "text-[#B3B9C6]"
)}
className={clsx("text-body-large", isSelected ? "text-[#3560C0]" : "")}
>
{text}
</p>
<Check size={24} color={isSelected ? "#3560C0" : "#B3B9C6"} />
<Check size={24} className={isSelected ? "text-[#3560C0]" : ""} />
</div>
);
}
4 changes: 1 addition & 3 deletions src/app/_components/SurveyScreen/hooks/usePostSurvey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { postSurvey } from "@/lib/apis/survey";
import { SurveyRequest } from "@/lib/type";

export function usePostSurvey() {
const [isLoading, setIsLoading] = useState(true);
const [isLoading, setIsLoading] = useState(false);
const [isError, setIsError] = useState(false);

const router = useRouter();
Expand Down Expand Up @@ -34,8 +34,6 @@ export function usePostSurvey() {
} catch (err) {
console.error(err);
setIsError(true);
} finally {
setIsLoading(false);
}
};

Expand Down
11 changes: 1 addition & 10 deletions src/app/_components/SurveyScreen/hooks/useSurvey.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useState } from "react";
import { useRouter } from "next/navigation";
import { surveyData } from "@/constants/surveyData";

interface UseSurveyProps {
Expand All @@ -8,8 +7,6 @@ interface UseSurveyProps {
}

export function useSurvey({ type, routing }: UseSurveyProps) {
const router = useRouter();

const questions = surveyData[type];
const storageKey = `${type}Answers`;

Expand All @@ -19,11 +16,7 @@ export function useSurvey({ type, routing }: UseSurveyProps) {

const [currentQuestion, setCurrentQuestion] = useState(0);

const progress =
((questions.length -
answers.filter((element: string) => element === "").length) /
questions.length) *
100;
const progress = ((currentQuestion + 1) / questions.length) * 100;

const handleAnswerClick = (answer: string) => {
const updatedAnswers = [...answers];
Expand All @@ -40,8 +33,6 @@ export function useSurvey({ type, routing }: UseSurveyProps) {
if (currentQuestion === questions.length - 1) {
if (routing) {
routing("ToMoodTransition");
} else {
router.push("/recommend");
}
} else {
setCurrentQuestion((prev) => prev + 1);
Expand Down
53 changes: 29 additions & 24 deletions src/app/_components/SurveyScreen/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
"use client";

import { useSurvey } from "./hooks/useSurvey";
import { usePostSurvey } from "./hooks/usePostSurvey";
import clsx from "clsx";
import ProgressBar from "@/app/_components/SurveyScreen/ProgressBar";
import SurveyOption from "./SurveyOption";
import Button from "@/components/Button";
import clsx from "clsx";
import { usePostSurvey } from "./hooks/usePostSurvey";
import TransitionScreen from "@/app/_components/TransitionScreen";
import ErrorScreen from "@/components/ErrorScreen";

interface SurveyScreenProps {
Expand All @@ -29,31 +30,36 @@ export default function SurveyScreen({ type, routing }: SurveyScreenProps) {
const isLastQuestion =
type === "todayMood" && currentQuestion === questions.length - 1;

if (isLoading && isLastQuestion) {
return <TransitionScreen type="toRecommend" />;
}
if (isError) return <ErrorScreen />;

return (
<div className="flex h-screen w-full flex-col items-center justify-between">
<div className="flex h-screen w-full flex-col items-center">
<ProgressBar progress={progress} />
<div className="flex w-[700px] flex-col justify-center gap-[64px]">
<div className="flex flex-col justify-between gap-[12px]">
<h2 className="text-heading-small text-[#1F2229]">
{questions[currentQuestion].title}
</h2>
<p className="text-title-small text-[#79839A]">
{questions[currentQuestion].contents}
</p>
</div>
<div className="flex w-[700px] flex-col justify-between gap-[12px]">
{questions[currentQuestion].items.map((item, index) => (
<SurveyOption
key={index}
text={item}
isSelected={item === answers[currentQuestion]}
onClick={() => handleAnswerClick(item)}
/>
))}
<div className="items my-[50px] flex h-full w-full max-w-[700px] flex-col justify-between gap-10 px-5 sm:justify-center sm:gap-16 sm:p-0">
<div className="flex flex-col gap-10 sm:gap-16">
<div className="flex flex-col gap-1 sm:gap-3">
<h2 className="text-title-medium sm:text-heading-small text-[#1F2229]">
{questions[currentQuestion].title}
</h2>
<p className="text-title-small text-[#79839A]">
{questions[currentQuestion].contents}
</p>
</div>
<div className="flex w-full max-w-[700px] flex-col gap-3">
{questions[currentQuestion].items.map((item, index) => (
<SurveyOption
key={index}
text={item}
isSelected={item === answers[currentQuestion]}
onClick={() => handleAnswerClick(item)}
/>
))}
</div>
</div>
<div className="flex items-center gap-[12px] self-end">
<div className="flex justify-end gap-3">
{currentQuestion > 0 && (
<Button
color="gray"
Expand All @@ -70,13 +76,12 @@ export default function SurveyScreen({ type, routing }: SurveyScreenProps) {
"text-body-large h-[62px] rounded-xl",
isLastQuestion ? "w-[166px]" : "w-[120px]"
)}
disabled={!answers[currentQuestion] || !isLoading}
disabled={!answers[currentQuestion]}
>
{isLastQuestion ? "추천길 보러가기" : "다음"}
</Button>
</div>
</div>
<div></div>
</div>
);
}
2 changes: 1 addition & 1 deletion src/app/_components/TransitionScreen/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default function TransitionScreen({
if (routing) {
setTimeout(() => {
routing("TodayMoodSurvey");
}, 1000);
}, 1800);
}
}, [transitionContent, routing]);

Expand Down
10 changes: 8 additions & 2 deletions src/app/globals.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
@import "tailwindcss";

@media (hover: hover) {
.hover-underline:hover {
text-decoration: underline;
}
}

@custom-variant hover (&:hover);

body {
font-family:
"Pretendard Variable",
Expand All @@ -19,8 +27,6 @@ body {
sans-serif;
}

@import "tailwindcss";

@theme {
/* Display */
--text-display: 36px;
Expand Down
17 changes: 17 additions & 0 deletions src/app/recommend/_components/RecommendationPanel/SkeletonCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Skeleton from "@/components/Loading/Skeleton";

export default function SkeletonCard() {
return (
<div className="flex h-full w-full animate-pulse gap-2 sm:flex-col sm:gap-3">
<div className="size-40 rounded-[6px] sm:h-[180px] sm:w-full" />
<div className="flex flex-1 flex-col gap-2">
<Skeleton width="80%" height="1rem" />
<Skeleton width="60%" height="0.875rem" />
<div className="mt-2 flex gap-2">
<Skeleton width="60px" height="1.5rem" className="rounded-[6px]" />
<Skeleton width="40px" height="1.5rem" className="rounded-[6px]" />
</div>
</div>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function SpaceCard({
onClick={() => {
window.open(url, "_blank");
}}
className="flex h-full w-full cursor-pointer gap-2 hover:bg-[#D1D4DC] sm:flex-col sm:gap-3"
className="flex h-full w-full cursor-pointer gap-2 sm:flex-col sm:gap-3"
>
<Image
className="size-40 rounded-[6px] object-cover sm:h-[180px] sm:w-full"
Expand Down
9 changes: 9 additions & 0 deletions src/app/recommend/_components/RecommendationPanel/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { RecommendationResponse } from "@/lib/type";
import SpaceCard from "./SpaceCard";
import ErrorScreen from "@/components/ErrorScreen";
import SkeletonCard from "./SkeletonCard";

export default function RecommendationPanel({
spaceData,
isLoading,
isError,
}: {
spaceData: RecommendationResponse[];
isLoading: boolean;
isError: boolean;
}) {
return (
Expand All @@ -26,6 +29,12 @@ export default function RecommendationPanel({

{isError ? (
<ErrorScreen />
) : isLoading ? (
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2 sm:gap-5">
{Array.from({ length: 6 }).map((_, index) => (
<SkeletonCard key={index} />
))}
</div>
) : (
<div className="scrollbar-overlay grid grid-cols-1 gap-3 sm:grid-cols-2 sm:gap-5 sm:overflow-x-auto">
{spaceData.map((space, index) => (
Expand Down
29 changes: 29 additions & 0 deletions src/app/recommend/_components/SatisfactionModalButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Button from "@/components/Button";

export default function SatisfactionModalButton({
onOpen,
}: {
onOpen: () => void;
}) {
return (
<div className="group relative flex flex-col gap-4">
<div className="flex justify-end">
<Button
color="blue"
onClick={onOpen}
className="text-body-small sm:text-body-large h-[37px] w-[107px] rounded-md sm:h-[62px] sm:w-[149px] sm:rounded-xl"
>
서비스 만족도
</Button>
</div>
<div className="relative hidden w-[300px] rounded-xl bg-[#353A46] p-3 text-white opacity-80 duration-100 group-hover:block">
<p className="text-body-small flex justify-center text-center">
서비스 이용은 어떠셨나요?
<br />
소중한 의견으로 더 나은 서비스를 만들게요!
</p>
<div className="absolute right-3 bottom-full h-0 w-0 border-x-8 border-b-8 border-x-transparent border-b-[#353A46] opacity-80" />
</div>
</div>
);
}
19 changes: 7 additions & 12 deletions src/app/recommend/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,15 @@ import { useGetRecommendation } from "./_hooks/useGetRecommendation";
import NavBar from "./_components/NavBar";
import RecommendationPanel from "./_components/RecommendationPanel";
import MapView from "./_components/MapView";
import Button from "@/components/Button";
import Modal from "@/components/Modal";
import SatisfactionModalContent from "./_components/SatisfactionModalContent";
import TransitionScreen from "@/app/_components/TransitionScreen";
import SatisfactionModalButton from "./_components/SatisfactionModalButton";

export default function RecommendPage() {
const [isOpen, setIsOpen] = useState(false);

const { spaceData, isLoading, isError } = useGetRecommendation();

if (isLoading) return <TransitionScreen type="toRecommend" />;

return (
<>
<div className="relative h-screen overflow-hidden bg-white">
Expand All @@ -28,16 +25,14 @@ export default function RecommendPage() {
<div className="pointer-events-none relative z-10">
<div className="flex h-screen flex-col sm:flex-row">
<NavBar />
<RecommendationPanel spaceData={spaceData} isError={isError} />
<RecommendationPanel
spaceData={spaceData}
isLoading={isLoading}
isError={isError}
/>
</div>
<div className="pointer-events-auto fixed top-14 right-4 flex gap-2 sm:top-5 sm:right-5 sm:gap-5">
<Button
color="blue"
onClick={() => setIsOpen(true)}
className="text-body-small sm:text-body-large h-[37px] w-[107px] rounded-md sm:h-[62px] sm:w-[149px] sm:rounded-xl"
>
서비스 만족도
</Button>
<SatisfactionModalButton onOpen={() => setIsOpen(true)} />
</div>
</div>
</div>
Expand Down
41 changes: 33 additions & 8 deletions src/app/submit-success/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
"use client";

import { useRouter } from "next/navigation";
import Link from "next/link";
import Button from "@/components/Button";
import Image from "next/image";
import SurveyComplete from "@/assets/images/survey-complete.png";

const GOOGLE_FORM_LINK =
"https://docs.google.com/forms/d/e/1FAIpQLSe5OJjg2hqPTtCszkh10CwrS39eVCf_iFfmP-21ago8KUL42w/viewform?usp=dialog";

export default function SubmitSuccessPage() {
const router = useRouter();
Expand All @@ -13,17 +17,38 @@ export default function SubmitSuccessPage() {
};

return (
<div className="m-auto flex h-screen w-full flex-col items-center justify-center gap-10">
<h2 className="text-display">설문에 응해주셔서 감사합니다</h2>
<Link href="https://www.google.co.kr/" className="text-slate-700">
서비스를 평가하고 아메리카노를 받아가세요!
</Link>
<div className="flex h-screen w-full flex-col items-center justify-between bg-gradient-to-t from-[#EBF0FA] to-white px-5 pb-10 sm:justify-center sm:gap-10 sm:p-0">
<div className="flex flex-1 flex-col items-center justify-center gap-6 sm:flex-none sm:gap-20">
<Image
src={SurveyComplete}
className="size-[150px] sm:size-[320px]"
alt=""
/>
<div className="flex flex-col gap-4 sm:gap-5">
<h2 className="text-title-large sm:text-heading-large text-center">
설문 완료!
<br />
이제 커피 받으러 가볼까요?
</h2>
<button
onClick={() => {
window.open(GOOGLE_FORM_LINK, "_blank");
}}
className="sm:text-body-large text-body-medium flex"
>
👉
<p className="cursor-pointer text-[#3560C0] underline transition-colors duration-100 hover:text-[#2A4C98] active:text-[#1F3870]">
서비스를 평가하고 아메리카노를 받아가세요!
</p>
</button>
</div>
</div>
<Button
color="blue"
className="text-body-large h-[62px] w-full max-w-[335px] rounded-xl sm:w-[335px]"
className="text-body-large h-[62px] w-full max-w-[250px] rounded-xl sm:w-[250px]"
onClick={handleRetrySurvey}
>
다시 설문조사하기
다시 추천받기
</Button>
</div>
);
Expand Down
Binary file modified src/assets/images/commute_recommendation.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/assets/images/mood_finder.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/survey-complete.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading