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
1 change: 1 addition & 0 deletions next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { withSentryConfig } from "@sentry/nextjs";
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
deviceSizes: [640, 750, 828, 1080, 1280, 1920],
unoptimized: true,
remotePatterns: [
{
Expand Down
11 changes: 3 additions & 8 deletions src/actions/user-check-action.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,26 @@
"use server";

import { IUser } from "@/types/user";
import { getCookieOfToken } from "@/utils/cookieToken";

const userCheckAction = async () => {
const TOKEN = await getCookieOfToken();

const userCheckAction = async (token: string) => {
try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_API_URL}/auths/user`,
{
method: "GET",
headers: {
Authorization: `Bearer ${TOKEN}`,
Authorization: `Bearer ${token}`,
},
},
);

// 유저 정보 확인 실패
if (!response.ok) {
throw new Error(await response.text());
}

// 유저 정보 확인 성공 시 image null 처리
// 유저 정보 받아와서 image null 처리
const resUser: IUser = await response.json();
resUser.image = resUser.image || "";

return {
status: true,
user: resUser,
Expand Down
17 changes: 8 additions & 9 deletions src/actions/user-signin-action.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
"use server";

import { setCookieOfToken } from "@/utils/cookieToken";

import userCheckAction from "./user-check-action";

// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
Expand All @@ -23,24 +21,25 @@ const userSignInAction = async (_: any, formData: FormData) => {
},
);

// 로그인 실패
// 토큰 받아오기 실패
if (!response.ok) {
throw new Error(await response.text());
const errorText = await response.text();
console.error("API 응답 오류:", errorText);
throw new Error(errorText);
}

// 토큰을 받아오면 쿠키에 저장
const res = await response.json();
await setCookieOfToken(res.token);

// 로그인 성공 시 유저 정보 확인
const chkResult = await userCheckAction();
// 유저 정보 확인
const chkResult = await userCheckAction(res.token);

// 유저 정보 확인 실패
// 유저 정보 확인 성공
if (!chkResult.status) {
throw new Error(chkResult.error);
}

// 유저 정보 반환
// 성공시 유저 정보 반환
return {
status: true,
error: "",
Expand Down
2 changes: 0 additions & 2 deletions src/actions/user-signup-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,10 @@ const userSignUpAction = async (_: any, formData: FormData) => {
},
);

// 회원가입 실패
if (!response.ok) {
throw new Error(await response.text());
}

// 회원가입 성공
return {
status: true,
error: "",
Expand Down
67 changes: 37 additions & 30 deletions src/app/(home)/_components/MainBanner.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,52 @@
"use client";

import "swiper/css";
import "swiper/css/effect-fade";

import { AnimatePresence, motion } from "framer-motion";
import Image from "next/image";
import Link from "next/link";
import { useEffect, useState } from "react";

import { MAIN_BANNER_ITEMS } from "@/constants/ui";

const MainBanner = () => {
const animatedTexts = ["러닝", "게임", "음악", "치맥"];
const [currentIndex, setCurrentIndex] = useState(0);

useEffect(() => {
const interval = setInterval(() => {
setCurrentIndex(prevIndex => (prevIndex + 1) % animatedTexts.length);
}, 3000); // 3초마다 텍스트,슬라이드 변경
setCurrentIndex(prev => (prev + 1) % MAIN_BANNER_ITEMS.length);
}, 3000);

return () => clearInterval(interval);
}, [animatedTexts.length]);
}, []);

return (
<section className="relative h-[50vh] max-h-[500px] w-full overflow-hidden md:h-[90vh] md:max-h-[1080px]">
<AnimatePresence mode="popLayout">
<motion.div
key={currentIndex}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.9, ease: "easeInOut" }}
className="relative h-full w-full"
>
<Image
src={`/images/main_slide${currentIndex + 1}.jpg`}
alt={`main_banner_${animatedTexts[currentIndex]}`}
fill
sizes="(max-width: 1280px) 100vw, 1280px"
className="object-cover"
priority
/>
</motion.div>
</AnimatePresence>
<div className="base-wrap absolute bottom-0 left-0 right-0 z-10 flex h-full flex-col justify-end gap-5 p-10 px-5 text-3xl font-bold text-white md:py-28 md:text-5xl md:font-extrabold">
<Link
href={MAIN_BANNER_ITEMS[currentIndex].link}
className="relative h-[50vh] max-h-[500px] w-full overflow-hidden bg-gray-500 md:h-[90vh] md:max-h-[1080px]"
>
{/* 이미지 슬라이드 영역 */}
<div className="relative h-full w-full">
{MAIN_BANNER_ITEMS.map((item, index) => (
<div
key={index}
className={`absolute inset-0 transition-opacity duration-1000 ${
index === currentIndex ? "z-10 opacity-100" : "z-0 opacity-0"
}`}
>
<Image
src={item.image}
alt={`main_banner_${item.text}`}
fill
sizes="(max-width: 1280px) 100vw, 1280px"
className="object-cover"
placeholder="blur"
priority={index === 0}
/>
</div>
))}
</div>

{/* 텍스트 애니메이션 영역 */}
<div className="base-wrap absolute bottom-0 left-0 right-0 z-20 flex h-full flex-col justify-end gap-5 p-10 px-5 text-3xl font-bold text-white md:py-28 md:text-5xl md:font-extrabold">
<p>{"지친 일상을 잠시 멈추고"}</p>
<p className="overflow-hidden">
{"함께 "}
Expand All @@ -51,16 +57,17 @@ const MainBanner = () => {
initial={{ y: "110%" }}
animate={{ y: "0%" }}
exit={{ y: "-120%" }}
transition={{ duration: 0.5, ease: "easeInOut" }}
className="block"
>
{animatedTexts[currentIndex]}
{MAIN_BANNER_ITEMS[currentIndex].text}
</motion.span>
</AnimatePresence>
</span>
{" 어떠세요?"}
</p>
</div>
</section>
</Link>
);
};

Expand Down
5 changes: 3 additions & 2 deletions src/app/(home)/_components/MainCarouselItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ const MainCarouselItem = ({ gathering }: IMainCarouselItemProps) => {
href={`/gathering/detail/${gathering.id}`}
className="flex flex-col gap-2"
>
<div className="relative h-[150px] overflow-hidden rounded-lg md:h-[200px] lg:h-[250px]">
<div className="relative h-[150px] overflow-hidden rounded-lg bg-gray-200 md:h-[200px] lg:h-[250px]">
<Image
src={gathering.image || "/images/gathering_default.jpeg"}
alt="carousel-item"
alt={`gathering image - [${gathering.name}]`}
fill
sizes="(max-width: 768px) 150px, (max-width: 1024px) 240px, 260px"
className="object-cover transition-all duration-300 hover:scale-110"
priority
/>
</div>
<p className="line-clamp-1 font-medium text-gray-900">{gathering.name}</p>
Expand Down
2 changes: 1 addition & 1 deletion src/app/(home)/_components/MainReviewContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const MainReviewContent = () => {
<div className="flex flex-col items-center justify-center gap-5 sm:flex-row">
<Image
src="/images/logo.png"
alt="logo"
alt="logo-image"
width={130}
height={60}
sizes="130px"
Expand Down
12 changes: 10 additions & 2 deletions src/app/(home)/_components/animations/MainAnimation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,16 @@
import dynamic from "next/dynamic";
import { memo, useEffect, useState } from "react";

const Lottie = dynamic(() => import("lottie-light-react"), { ssr: false });

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

const Lottie = dynamic(() => import("lottie-light-react"), {
loading: () => (
<div className="flex h-[450px] w-[500px] items-center justify-center bg-gray-200 sm:h-[600px] md:h-full">
<LoadingSpinner size="lg" />
</div>
),
ssr: false,
});
interface IMainAnimationProps {
type: "online" | "offline";
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/all-reviews/[tab]/_components/ReviewListParent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const ReviewListParent = () => {
<ReviewCardList reviews={flatData} />
<div ref={setTarget} className="h-10 w-full">
{isFetchingNextPage && (
<div className="flex justify-center p-4">
<div className="flex justify-center py-8">
<LoadingSpinner size="lg" />
</div>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const GatheringImage = ({ id }: IGatheringImageProps) => {
<DeadlineTag registrationEnd={dayjs(data?.registrationEnd)} />
<Image
src={data.image || "/images/gathering_default.jpeg"}
alt="gathering-image"
alt={`모임-[${data.name}] 이미지`}
fill
sizes="(max-width: 768px) 90vw, 40vw"
className="object-cover"
Expand Down
24 changes: 12 additions & 12 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,13 @@
import "./globals.css";

import type { Metadata } from "next";
import dynamic from "next/dynamic";

import TokenValidator from "@/components/auth/TokenValidator";
import Footer from "@/components/layout/Footer";
import Header from "@/components/layout/Header";
import QueryProvider from "@/components/providers/QueryProvider";
import { FONT } from "@/constants/font";

const TokenValidator = dynamic(
() => import("@/components/auth/TokenValidator"),
{
ssr: false,
},
);

const Footer = dynamic(() => import("@/components/layout/Footer"), {
ssr: false,
});

export const metadata: Metadata = {
title: "PLAKE",
description:
Expand All @@ -31,6 +21,16 @@ export default function RootLayout({
}>) {
return (
<html lang="en">
<head>
<link
rel="preconnect"
href="https://fe-adv-project-together-dallaem.vercel.app"
/>
<link
rel="preconnect"
href="https://sprint-fe-project.s3.ap-northeast-2.amazonaws.com/together-dallaem"
/>
</head>
<body className={`${FONT.variable} antialiased`} suppressHydrationWarning>
<QueryProvider>
<Header />
Expand Down
1 change: 0 additions & 1 deletion src/assets/animations/offline.json

This file was deleted.

1 change: 0 additions & 1 deletion src/assets/animations/online.json

This file was deleted.

Binary file added src/assets/images/main_slide1.jpg
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/main_slide2.jpg
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/main_slide3.jpg
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/main_slide4.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/components/layout/MainCardContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const MainCardContent = ({
{name}
</p>
<RxDividerVertical className="text-gray-900" />
<span className="ml-[3px] min-w-16 text-sm text-gray-700">
<span className="ml-[3px] min-w-14 text-sm text-gray-700">
{location === ONLINE.location ? "온라인" : location}
</span>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/components/layout/MainCardImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ const MainCardImage = ({
registrationEnd,
}: IMainCardImageProps) => {
return (
<div className="relative h-[156px] w-full min-w-[280px] md:w-[280px] lg:w-[280px]">
<div className="relative h-[156px] w-full min-w-[280px] bg-gray-200 md:w-[280px] lg:w-[280px]">
<Image
src={image || "/images/gathering_default.jpeg"}
alt={image ? name : "모임 기본 이미지"}
className="h-full w-full object-cover"
fill
sizes="(max-width: 768px) 50vw"
></Image>
/>
<DeadlineTag registrationEnd={registrationEnd} />
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/layout/ReviewCardItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const ReviewCardItem = memo(({ review }: TReviewCardItemProps) => {
href={`/gathering/detail/${Gathering.id}`}
style={{ display: "contents" }}
>
<div className="relative min-h-[156px] w-full max-w-[280px] overflow-hidden rounded-3xl">
<div className="relative min-h-[156px] w-full overflow-hidden rounded-3xl md:max-w-[280px]">
<Image
src={Gathering.image ?? "https://picsum.photos/500/700"}
alt={Gathering.name}
Expand Down
29 changes: 29 additions & 0 deletions src/constants/ui.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
// 메인 배너 아이템
import mainBanner1 from "@/assets/images/main_slide1.jpg";
import mainBanner2 from "@/assets/images/main_slide2.jpg";
import mainBanner3 from "@/assets/images/main_slide3.jpg";
import mainBanner4 from "@/assets/images/main_slide4.jpg";

export const MAIN_BANNER_ITEMS = [
{
image: mainBanner1,
text: "러닝",
link: "/gathering/offline?type=exercise",
},
{
image: mainBanner2,
text: "게임",
link: "/gathering/online",
},
{
image: mainBanner3,
text: "음악",
link: "/gathering/offline?type=art",
},
{
image: mainBanner4,
text: "치맥",
link: "/gathering/offline?type=dining",
},
] as const;

// 메인 탭
export const MAIN_TAB = [
{ name: "오프라인", value: "", href: "/gathering/offline" },
Expand Down