diff --git a/package-lock.json b/package-lock.json index aae2d1b..788f8d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "lucide-react": "^0.344.0", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-icons": "^5.4.0", + "react-icons": "^5.5.0", "react-query": "^3.39.3", "react-quill": "^2.0.0", "react-router-dom": "^6.22.1" @@ -6078,9 +6078,9 @@ } }, "node_modules/react-icons": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.4.0.tgz", - "integrity": "sha512-7eltJxgVt7X64oHh6wSWNwwbKTCtMfK35hcjvJS0yxEAhPM8oUKdS3+kqaW1vicIltw+kR2unHaa12S9pPALoQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", + "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", "license": "MIT", "peerDependencies": { "react": "*" diff --git a/package.json b/package.json index 6ffd55e..6a99eaa 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "lucide-react": "^0.344.0", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-icons": "^5.4.0", + "react-icons": "^5.5.0", "react-query": "^3.39.3", "react-quill": "^2.0.0", "react-router-dom": "^6.22.1" diff --git a/src/assets/img/support/support_banner.png b/src/assets/img/support/support_banner.png new file mode 100644 index 0000000..b1936e2 Binary files /dev/null and b/src/assets/img/support/support_banner.png differ diff --git a/src/assets/img/support/support_process_group1.svg b/src/assets/img/support/support_process_group1.svg new file mode 100644 index 0000000..08273d7 --- /dev/null +++ b/src/assets/img/support/support_process_group1.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/assets/img/support/support_process_group2.svg b/src/assets/img/support/support_process_group2.svg new file mode 100644 index 0000000..3a2a4df --- /dev/null +++ b/src/assets/img/support/support_process_group2.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index 4d28d35..400c2a7 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -35,7 +35,8 @@ const menuItems = [ label: "GALLERY", hasDropdown: false, path: "/gallery", - } + }, + { label: "SUPPORT", path: "/support", hasDropdown: false }, /* { label: "NEWS", hasDropdown: false }, { label: "SUPPORT", hasDropdown: false }, { label: "COC", hasDropdown: false },*/ diff --git a/src/components/SupportCards/SupportCards.tsx b/src/components/SupportCards/SupportCards.tsx new file mode 100644 index 0000000..8215dd7 --- /dev/null +++ b/src/components/SupportCards/SupportCards.tsx @@ -0,0 +1,111 @@ +import React from 'react'; +import { IoIosArrowForward } from 'react-icons/io'; +import financialIcon from '@/assets/img/support/support_process_group1.svg'; +import materialIcon from '@/assets/img/support/support_process_group2.svg'; + +interface SupportCardProps { + subtitle: string; + title: string; + description: string[]; + icon: string; +} + +const SupportCard: React.FC = ({ subtitle, title, description, icon }) => ( +
+
+
+
+
+
+ {subtitle} +
+
+ {title} +
+
+
+ {description.map((line, index) => ( + + {line} + {index < description.length - 1 &&
} +
+ ))} +
+
+
+ {`${title} +
+
+
+); + +const SupportCards = () => { + const supportCards = [ + { + subtitle: "작은 나눔 큰 변화", + title: "금전적 후원", + description: [ + "계좌이체를 통해 후원금을 입금하실 수 있습니다.", + "여러분의 소중한 후원은 큰 힘이 됩니다." + ], + icon: financialIcon + }, + { + subtitle: "나누는 기쁨", + title: "물품 기부", + description: [ + "도서 및 이벤트 상품 등 다양한 물품 기부를 받습니다.", + "기부 물품을 구체적으로 작성해주시면,", + "이메일로 절차를 안내해 드리겠습니다." + ], + icon: materialIcon + } + ]; + + const handleApplicationClick = () => { + window.open('https://forms.gle/your-google-form-id', '_blank'); + }; + + return ( +
+ {/* Cards Container */} +
+ {supportCards.map((card, index) => ( + + ))} +
+ + {/* Application Card */} +
+
+
+
+ 후원 신청하기 +
+
+ 아래 구글폼을 통해 후원에 필요한 정보를 입력해 주세요. +
+ 제출하신 정보는 내부 검토 후, 후원 방법에 대해 안내드리겠습니다. +
+
+
+ +
+
+
+ ); +}; + +export default SupportCards; \ No newline at end of file diff --git a/src/components/Timeline/Timeline.tsx b/src/components/Timeline/Timeline.tsx new file mode 100644 index 0000000..a6c1e7a --- /dev/null +++ b/src/components/Timeline/Timeline.tsx @@ -0,0 +1,155 @@ +import React, { useState, useEffect } from 'react'; +import { IoIosArrowBack, IoIosArrowForward } from 'react-icons/io'; +import { AboutSectionTitle } from '../AboutSection'; + +const Timeline = () => { + const [currentSlide, setCurrentSlide] = useState(0); + const [slidesToShow, setSlidesToShow] = useState(1); + + const events = [ + { + year: 24, + month: 'SEP', + title: 'HelloPY 탄생', + description: '파이몬 생일\nDiscord, Instagram, Youtube 개설', + position: 'right' + }, + + { + year: 24, + month: 'OCT', + title: '컨퍼런스 & 파이콘', + description: 'HelloPY 컨퍼런스 VOL.1\n파이콘 한국 2024 부스 운영\nDiscord User 100명 달성', + position: 'left' + }, + { + year: 24, + month: 'NOV', + title: '제1회 OnOFF 모각클', + description: "'모여서 각자 작업하는 모임'\n매주 2회 대면/비대면 활동 개최", + position: 'right' + }, + { + year: 24, + month: 'DEC', + title: '파이콘 공유회', + description: '월드와이드 파이콘 공유회\nLinkedIn 개설', + position: 'left' + }, + { + year: 25, + month: 'MAR', + title: '홈페이지 리뉴얼', + description: 'HelloPY 공식 홈페이지 제작', + position: 'right' + }, + ]; + + useEffect(() => { + const handleResize = () => { + if (window.innerWidth >= 1024) { // lg breakpoint + setSlidesToShow(3); + } else if (window.innerWidth >= 768) { // md breakpoint + setSlidesToShow(2); + } else { + setSlidesToShow(1); + } + }; + + handleResize(); // 초기 설정 + window.addEventListener('resize', handleResize); + return () => window.removeEventListener('resize', handleResize); + }, []); + + const handlePrevSlide = () => { + setCurrentSlide((prev) => (prev > 0 ? prev - 1 : events.length - slidesToShow)); + }; + + const handleNextSlide = () => { + setCurrentSlide((prev) => (prev < events.length - slidesToShow ? prev + 1 : 0)); + }; + + const isFirstSlide = currentSlide === 0; + const isLastSlide = currentSlide >= events.length - slidesToShow; + + return ( +
+
+
+ + + {/* Timeline Events Container */} +
+
+
+ {events.map((event, index) => ( +
+
+
+
+
+
+ {event.year}.{event.month} +
+
+ {event.title} +
+
+
+ {event.description} +
+
+
+
+ ))} +
+
+ + {/* Navigation Buttons */} +
+ + +
+
+
+
+ ); +}; + +export default Timeline; \ No newline at end of file diff --git a/src/pages/gallery/$id.tsx b/src/pages/gallery/$id.tsx index cf8cc58..f03de9b 100644 --- a/src/pages/gallery/$id.tsx +++ b/src/pages/gallery/$id.tsx @@ -1,37 +1,34 @@ import * as React from "react"; import { Container } from "@/components/Container"; -import { useGetNotice } from "@/quries/useGetNotice.ts"; import { useNavigate, useParams } from "react-router-dom"; +import { useGetGalleryItem } from "@/quries/useGetGalleryItem"; export const NoticeDetail: React.FC = () => { const { id } = useParams(); const nav = useNavigate(); - const { data } = useGetNotice(id); + const { data } = useGetGalleryItem(id ? Number(id) : undefined); const goToList = () => { - nav("/board/notice"); + nav("/gallery"); }; - const notice = data?.data ?? undefined; + const galleryItem = data?.data ?? undefined; return ( - notice && ( + galleryItem && (

공지사항

- {notice.title} + {galleryItem.title}

-

- {new Date(notice.created_at).toLocaleDateString()} -

{/* REVIEW: 해시태그 컴포넌트는 없나? todo: hashtag*/} - {/*
#컨퍼런스
*/} + {galleryItem?.tags?.map((tag:{id: number, name: string}) =>
{tag.name}
)}
-

+

diff --git a/src/pages/gallery/index.tsx b/src/pages/gallery/index.tsx index e28dcc7..5034543 100644 --- a/src/pages/gallery/index.tsx +++ b/src/pages/gallery/index.tsx @@ -1,4 +1,3 @@ - import BgImg from "@/assets/img/gallery/banner_gallery.png"; import { HeaderBanner } from "@/components/HeaderBanner"; @@ -10,6 +9,7 @@ import { useEffect, useState } from "react"; import { Gallery, SelectValue } from "@/types/common.ts"; import { useGetGallery } from "@/quries/useGetGallery"; import { Pagination } from "@/components/Pagination"; +import Timeline from '@/components/Timeline/Timeline'; const selectedOptions = [ { label: "2024년", value: "2024" }, @@ -84,7 +84,7 @@ const ActivityGallery = () => {
- +
diff --git a/src/pages/support/index.tsx b/src/pages/support/index.tsx new file mode 100644 index 0000000..63bd6c6 --- /dev/null +++ b/src/pages/support/index.tsx @@ -0,0 +1,41 @@ +import BgImg from "@/assets/img/support/support_banner.png"; + +import { HeaderBanner } from "@/components/HeaderBanner"; +import { Breadcrumb } from "@/components/Breadcrumb"; +import { AboutSection, AboutSectionTitle } from "@/components/AboutSection"; +import SupportCards from '../../components/SupportCards/SupportCards'; + + +const Support = () => { + + return ( +
+ 많은 관심과 참여부탁드립니다.`} + > + Home, + SUPPORT + ]} + /> + + + + + + +
+ ); +}; + +export default Support; diff --git a/src/quries/useGetGalleryItem.ts b/src/quries/useGetGalleryItem.ts new file mode 100644 index 0000000..ba469ac --- /dev/null +++ b/src/quries/useGetGalleryItem.ts @@ -0,0 +1,10 @@ +import { useQuery } from "react-query"; +import { GalleryService } from "@/service/galleryService"; + +export const useGetGalleryItem = (id?: number) => { + return useQuery({ + enabled: !!id, + queryKey: [GalleryService.QueryKey.getGallery, id], + queryFn: () => GalleryService.getGallery(id!), + }); +}; diff --git a/src/service/galleryService.ts b/src/service/galleryService.ts index b548336..f8baaba 100644 --- a/src/service/galleryService.ts +++ b/src/service/galleryService.ts @@ -3,12 +3,18 @@ import instance from "@/hooks/useAxios.ts"; export const GalleryService = { QueryKey: { getGallery: "getGallery", + getGalleryItem: "getGalleryItem", }, getGallery: async (page: number) => { const { data } = await instance.get(`/activity-gallery/?page_size=10&page=${page}`); + return data; + }, + getGalleryItem: async (id: number) => { + const { data } = await instance.get(`/activity-gallery${id}`); + return data; }, };