Skip to content
Merged
Binary file added Mine/src/assets/explorebg.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 Mine/src/assets/savedbg.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 11 additions & 4 deletions Mine/src/components/settings/ScreenSettings.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState, useRef } from 'react'
import { useState, useRef, useEffect } from 'react'
import { useParams } from 'react-router-dom'
import IconWandStars from '../../icon/wand_stars.svg?react'
import IconAddPhoto from '../../icon/add_photo_alternate.svg?react'
Expand Down Expand Up @@ -29,7 +29,6 @@ export default function ScreenSettings() {
const { imageUrl } = await uploadImage(file)
await patchCover({ id: Number(magazineId), coverImageUrl: imageUrl })
setShowToast(true)
setTimeout(() => setShowToast(false), 3000)
} catch (error) {
console.error('이미지 업로드 실패:', error)
}
Expand All @@ -42,14 +41,22 @@ export default function ScreenSettings() {
await createMoodboard(Number(magazineId))
setIsConfirmOpen(false)
setShowToast(true)
setTimeout(() => setShowToast(false), 3000)
} catch (error) {
console.error('무드보드 생성 실패:', error)
} finally {
setIsLoading(false)
}
}

useEffect(() => {
if (showToast) {
const timerId = setTimeout(() => {
setShowToast(false)
}, 3000)
return () => clearTimeout(timerId)
}
}, [showToast])

return (
<>
<div className="w-136.5 h-36.5 flex gap-6.5">
Expand Down Expand Up @@ -88,4 +95,4 @@ export default function ScreenSettings() {
)}
</>
)
}
}
8 changes: 2 additions & 6 deletions Mine/src/pages/landing/LandingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,8 @@ export default function LandingPage() {

return (
<div
className="relative min-h-screen w-screen overflow-hidden"
style={{
backgroundImage: `url(${landingBg})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
}}
className="relative min-h-screen w-screen overflow-hidden bg-center bg-cover"
style={{ backgroundImage: `url(${landingBg})` }}
>
<div className="absolute inset-0 bg-black/45" />
<Minelogo className="absolute left-20 top-17 w-35 h-17.5 z-20" />
Expand Down
36 changes: 31 additions & 5 deletions Mine/src/pages/magazine/ExplorePage.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { useEffect, useRef } from 'react'
import ExploreGrid from './components/ExploreGrid'
import useGetMagazineFeed from '../../hooks/useGetMagazineFeed'
import explorebg from '../../assets/explorebg.jpg'
import useSidebarStore from '../../stores/sidebar'

export default function ExplorePage() {
const { isOpen } = useSidebarStore()
const { data, fetchNextPage, hasNextPage, isFetchingNextPage } = useGetMagazineFeed()
const observerRef = useRef<HTMLDivElement>(null)

Expand All @@ -23,10 +26,33 @@ export default function ExplorePage() {
}, [hasNextPage, isFetchingNextPage, fetchNextPage])

return (
<div className="min-h-screen pt-39.25 pb-10 px-32.75 relative">
<ExploreGrid magazines={magazines} />
<div ref={observerRef} className="h-10" />
{isFetchingNextPage && <div className="text-center py-4">로딩중...</div>}
<div
className="min-h-screen pt-39.25 pb-10 relative bg-center bg-cover min-w-300"
style={{
backgroundImage: `url(${explorebg})`,
backgroundAttachment: 'fixed',
}}
>
{/* 어두운 오버레이 */}
<div className="absolute inset-0 bg-gray-600-op30 pointer-events-none" />

{/* 상단 흰색 그라디언트 */}
<div
className="fixed top-0 left-0 w-full pointer-events-none z-10"
style={{
height: '244px',
background:
'linear-gradient(180deg, rgba(255, 255, 255, 0.40) 29.51%, rgba(255, 255, 255, 0.00) 93.65%)',
}}
/>

<div className="relative z-20 flex justify-center">
<div className={`transition-all duration-200 ${isOpen ? 'ml-60' : 'ml-15'}`}>
<ExploreGrid magazines={magazines} />
<div ref={observerRef} className="h-10" />
{isFetchingNextPage && <div className="text-center py-4">로딩중...</div>}
</div>
</div>
</div>
)
}
}
101 changes: 56 additions & 45 deletions Mine/src/pages/magazine/SavedMagazinePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,65 +2,76 @@ import { useState } from 'react'
import SavedMagazineItem from './components/SavedMagazineItem'
import ArrowPagination from './components/ArrowPagination'
import useGetLikedMagazineList from '../../hooks/useGetLikedMagazineList'
import savedbg from '../../assets/savedbg.jpg'

const CARD_WIDTH = 476
const GAP = 16
const COLUMN_STEP = CARD_WIDTH + GAP
const COLUMNS_PER_VIEW = 2
const COLUMN_STEP = (CARD_WIDTH + GAP) * COLUMNS_PER_VIEW
const ITEMS_PER_COLUMN = 2

export default function SavedMagazinePage() {
const [columnIndex, setColumnIndex] = useState(0)
const [columnIndex, setColumnIndex] = useState(0)

const { data, isLoading, isError } = useGetLikedMagazineList({
page: 0,
size: 20,
sort: ['createdAt,desc'],
})
const { data, isLoading, isError } = useGetLikedMagazineList({
page: 0,
size: 20,
sort: ['createdAt,desc'],
})

if (isLoading) return <div>로딩중...</div>
if (isError) return <div>불러오기 실패</div>
if (isLoading) return <div>로딩중...</div>
if (isError) return <div>불러오기 실패</div>

const magazines = data?.content ?? []
const magazines = data?.content ?? []

if (magazines.length === 0) {
return <div className="p-10">찜한 매거진이 아직 없어요.</div>
}
if (magazines.length === 0) {
return <div className="p-10">찜한 매거진이 아직 없어요.</div>
}

const columns = Array.from({ length: Math.ceil(magazines.length / ITEMS_PER_COLUMN) }, (_, i) =>
magazines.slice(i * ITEMS_PER_COLUMN, i * ITEMS_PER_COLUMN + ITEMS_PER_COLUMN),
)
const columns = Array.from({ length: Math.ceil(magazines.length / ITEMS_PER_COLUMN) }, (_, i) =>
magazines.slice(i * ITEMS_PER_COLUMN, i * ITEMS_PER_COLUMN + ITEMS_PER_COLUMN)
)

const TOTAL_COLUMNS = columns.length
const TOTAL_COLUMNS = columns.length
const TOTAL_PAGES = Math.ceil(TOTAL_COLUMNS / COLUMNS_PER_VIEW)

return (
<div className="relative min-h-screen bg-white overflow-x-hidden">
<div className="relative pt-25 pb-40 px-51.5">
<div className="relative">
<div className="pointer-events-none absolute left-0 top-0 bottom-0 w-51.5 z-10" />
return (
<div
className="relative min-h-screen overflow-x-hidden flex items-center bg-center bg-cover"
style={{
backgroundImage: `url(${savedbg})`,
backgroundAttachment: 'fixed',
}}
>
<div className="absolute inset-0 bg-gray-600-op30 pointer-events-none" />

<div className="relative overflow-x-visible overflow-y-visible w-full">
<div
className="flex gap-4 transition-transform duration-500 ease-in-out will-change-transform"
style={{ transform: `translateX(-${columnIndex * COLUMN_STEP}px)` }}
>
{columns.map((col, colIdx) => (
<div key={colIdx} className="flex flex-col gap-4 shrink-0">
{col.map((magazine) => (
<SavedMagazineItem key={magazine.magazineId} magazine={magazine} />
))}
<div className="relative w-full py-33.25 pl-66.5">
<div className="relative">
<div className="relative overflow-x-visible overflow-y-visible w-full">
<div
className="flex gap-4 transition-transform duration-500 ease-in-out will-change-transform"
style={{ transform: `translateX(-${columnIndex * COLUMN_STEP}px)` }}
>
{columns.map((col, colIdx) => (
<div key={colIdx} className="flex flex-col gap-4 shrink-0">
{col.map((magazine) => (
<SavedMagazineItem key={magazine.magazineId} magazine={magazine} />
))}
</div>
))}
</div>
</div>
</div>
))}

<ArrowPagination
currentPage={Math.min(columnIndex + 1, TOTAL_PAGES)}
totalPages={TOTAL_PAGES}
onNext={() =>
setColumnIndex((prev) => Math.min(prev + 1, TOTAL_PAGES * COLUMNS_PER_VIEW - COLUMNS_PER_VIEW))
}
onPrev={() => setColumnIndex((prev) => Math.max(prev - 1, 0))}
/>
</div>
</div>
</div>

<ArrowPagination
currentPage={Math.min(columnIndex + 1, TOTAL_COLUMNS)}
totalPages={TOTAL_COLUMNS}
onNext={() => setColumnIndex((prev) => Math.min(prev + 1, TOTAL_COLUMNS - 1))}
onPrev={() => setColumnIndex((prev) => Math.max(prev - 1, 0))}
/>
</div>
</div>
)
}
)
}
8 changes: 7 additions & 1 deletion Mine/src/pages/magazine/components/ExploreGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ interface ExploreGridProps {

export default function ExploreGrid({ magazines }: ExploreGridProps) {
return (
<div className="grid grid-cols-3 gap-4">
<div
className="grid"
style={{
gridTemplateColumns: 'repeat(3, 362px)',
gap: '8px',
}}
>
{magazines.map((magazine) => (
<ExploreItem key={magazine.magazineId} magazine={magazine} />
))}
Expand Down
10 changes: 3 additions & 7 deletions Mine/src/pages/magazine/components/ExploreItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,14 @@ export default function ExploreItem({ magazine }: Props) {

return (
<div
className="flex w-90.5 h-60 px-5 py-4 overflow-hidden cursor-pointer"
className="flex justify-end items-end w-90.5 h-60 px-5 py-4 overflow-hidden cursor-pointer bg-center bg-cover"
style={{
backgroundImage: safeImageUrl ? `url(${safeImageUrl})` : 'none',
backgroundSize: 'cover',
backgroundPosition: 'center',
backgroundColor: safeImageUrl ? 'transparent' : '#1a1a1a',
}}
onClick={() => navigate(`/magazine/${magazine.magazineId}`)}
>
<p className="flex mt-auto ml-auto font-notoserif font-semibold24 leading-none text-white text-right">
{magazine.title}
</p>
<p className="font-notoserif font-semibold24 leading-none text-white text-right">{magazine.title}</p>
</div>
)
}
}
48 changes: 23 additions & 25 deletions Mine/src/pages/magazine/components/SavedMagazineItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,33 @@ import { useNavigate } from 'react-router-dom'
import type { Magazine } from '../../../types/magazine'

type Props = {
magazine: Magazine
magazine: Magazine
}

const isValidUrl = (url: string) => {
try {
const parsed = new URL(url)
return parsed.protocol === 'https:'
} catch {
return false
}
try {
const parsed = new URL(url)
return parsed.protocol === 'https:'
} catch {
return false
}
}

export default function SavedMagazineItem({ magazine }: Props) {
const navigate = useNavigate()
const safeImageUrl = isValidUrl(magazine.coverImageUrl) ? magazine.coverImageUrl : ''
const navigate = useNavigate()
const safeImageUrl = isValidUrl(magazine.coverImageUrl) ? magazine.coverImageUrl : ''

return (
<div
className="flex w-119 h-67 p-[16px_20px] justify-end items-end gap-2.5 shrink-0 cursor-pointer"
style={{
backgroundImage: safeImageUrl ? `url(${safeImageUrl})` : 'none',
backgroundSize: 'cover',
backgroundPosition: 'center',
}}
onClick={() => navigate(`/magazine/${magazine.magazineId}`)}
>
<span className="text-white text-right leading-normal font-[MaruBuri] font-semibold24">
{magazine.title}
</span>
</div>
)
}
return (
<div
className="flex justify-end items-end shrink-0 cursor-pointer w-119 h-67 p-[16px_28px] bg-cover bg-center"
style={{
backgroundImage: safeImageUrl ? `url(${safeImageUrl})` : 'none',
}}
onClick={() => navigate(`/magazine/${magazine.magazineId}`)}
>
<span className="text-white text-right leading-normal font-notoserif font-semibold24">
{magazine.title}
</span>
</div>
)
}
8 changes: 2 additions & 6 deletions Mine/src/pages/main/GuestPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,8 @@ export default function GuestPage() {

return (
<div
className="relative w-full h-full flex flex-col items-center justify-center overflow-hidden"
style={{
backgroundImage: `url(${bg2})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
}}
className="relative w-full h-full flex flex-col items-center justify-center overflow-hidden bg-center bg-cover"
style={{ backgroundImage: `url(${bg2})` }}
>
<div className="absolute inset-0 bg-black/30" />
<div
Expand Down
8 changes: 2 additions & 6 deletions Mine/src/pages/main/MainPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,8 @@ export default function MainPage() {

return (
<div
className="flex flex-col items-center justify-center w-full h-full relative z-0 overflow-hidden"
style={{
backgroundImage: `url(${landingBg})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
}}
className="flex flex-col items-center justify-center w-full h-full relative z-0 overflow-hidden bg-cover bg-center"
style={{ backgroundImage: `url(${landingBg})` }}
>
<div className="absolute inset-0 bg-linear-to-r from-gray-500-op70 via-black/45 to-gray-500-op70 z-0" />
<div
Expand Down
Loading