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
5 changes: 5 additions & 0 deletions public/assets/menu/SelectedManual.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions public/assets/menu/help.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions public/assets/menu/manual.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 17 additions & 9 deletions src/features/home/ui/EventSliderSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,23 +38,30 @@ const EventSliderSection = ({ title, events }: EventSliderSectionProps) => {
const eventsToShow =
filteredEvents.length > 0
? filteredEvents
.slice(startIndex, startIndex + maxCardsToShow)
.concat(
startIndex + maxCardsToShow > filteredEvents.length
? filteredEvents.slice(0, (startIndex + maxCardsToShow) % filteredEvents.length)
: []
)
.slice(startIndex, startIndex + maxCardsToShow)
.concat(
startIndex + maxCardsToShow > filteredEvents.length
? filteredEvents.slice(0, (startIndex + maxCardsToShow) % filteredEvents.length)
: []
)
: [];

return (
<div className="relative w-full px-6">
<h2 className="sm:mb-3 md:mb-3.5 lg:mb-4 font-bold sm:text-sm md:text-base lg:text-lg">{title}</h2>
<div className="flex gap-4">
<div className="flex gap-4 justify-center">
{filteredEvents.length === 0 ? (
<div className="w-full text-center text-gray-500">표시할 이벤트가 없습니다.</div>
) : (
eventsToShow.map((event: EventItem) => (
<div key={event.id} className="w-full h-full min-h-[200px] max-w-sm min-w-[200px]">
<div
key={event.id}
className="
h-full min-h-[200px]
lg:min-w-[220px] sm:min-w-[160px] w-[100%] sm:w-[40%]
max-w-sm
"
>
<EventCard
key={event.id}
id={event.id}
Expand All @@ -69,6 +76,7 @@ const EventSliderSection = ({ title, events }: EventSliderSectionProps) => {
onClick={() => navigate(`/event-details/${event.id}`)}
/>
</div>

))
)}
{eventsToShow.length === 1 && (
Expand All @@ -83,7 +91,7 @@ const EventSliderSection = ({ title, events }: EventSliderSectionProps) => {
eventDate=""
location=""
hashtags={[]}
onClick={() => {}}
onClick={() => { }}
/>
</div>
)}
Expand Down
13 changes: 10 additions & 3 deletions src/pages/home/ui/MainPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import useAuthStore from '../../../app/provider/authStore';
import EventTags from '../../../features/home/ui/EventTags';
import ProfileCircle from '../../../../design-system/ui/Profile';
import useEventList from '../../../entities/event/hook/useEventListHook';

import FloatingButton from '../../../shared/ui/FloatingButton';
import manualIcon from '../../../../public/assets/menu/help.svg';
import { USER_MANUAL_URL } from '../../../shared/types/menuType';
const MainPage = () => {
const navigate = useNavigate();
const { isModalOpen, openModal, closeModal, isLoggedIn, name } = useAuthStore();
Expand All @@ -35,13 +37,13 @@ const MainPage = () => {
};

return (
<div className="flex flex-col items-center pb-24">
<div className="relative flex flex-col items-center pb-24">
<Header
centerContent={
<SearchTextField
iconPath={<img src={searchIcon} alt="Search" />}
onClick={() => navigate('/search')}
onChange={() => {}}
onChange={() => { }}
placeholder="검색어를 입력해주세요"
/>
}
Expand Down Expand Up @@ -84,6 +86,11 @@ const MainPage = () => {
>
전체 이벤트 보러가기 <span className="ml-1.5">&gt;</span>
</button>
<div className="sticky w-full flex justify-end px-6 z-50">
<FloatingButton ariaLabel="사용법" onClick={() => window.open(USER_MANUAL_URL, '_blank')} className='bottom-24'>
<img src={manualIcon} alt="사용법" className="w-full h-full" />
</FloatingButton>
</div>
<BottomBar />
</div>
);
Expand Down
10 changes: 7 additions & 3 deletions src/pages/menu/ui/MenuPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ import Header from '../../../../design-system/ui/Header';
import { getButtonData } from '../../../shared/types/menuType';
import BottomBar from '../../../widgets/main/ui/BottomBar';

const handleIconClick = (navigate: (path: string) => void, path: string) => {
navigate(path);
const handleIconClick = (navigate: (path: string) => void, path: string, url?: string) => {
if (url) {
window.open(url, '_blank');
} else if (path) {
navigate(path);
}
};

const MenuPage = () => {
Expand All @@ -23,7 +27,7 @@ const MenuPage = () => {
iconPath={<img src={button.iconPath} alt={button.label} className="w-6 h-6 md:w-7 md:h-7" />}
hoverIconPath={<img src={button.hoverIconPath} alt={button.label} className="w-6 h-6 md:w-7 md:h-7" />}
label={button.label}
onClick={() => handleIconClick(navigate, button.path)}
onClick={() => handleIconClick(navigate, button.path, button.url)}
/>
{button.label !== '내 호스트' && index !== buttonData.length - 1 && (
<hr className="mt-5 border-[0.5px] border-gray4" />
Expand Down
8 changes: 8 additions & 0 deletions src/pages/menu/ui/myHost/MyHostPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import useHostChannelList from '../../../../entities/host/hook/useHostChannelLis
import useHostDetail from '../../../../entities/host/hook/useHostDetailHook';
import TertiaryButton from '../../../../../design-system/ui/buttons/TertiaryButton';
import useAuthStore from '../../../../app/provider/authStore';
import FloatingButton from '../../../../shared/ui/FloatingButton';
import manualIcon from '../../../../../public/assets/menu/help.svg';
import { HOST_MANUAL_URL } from '../../../../shared/types/menuType';

const MyHostPage = () => {
const [selectedHostId, setSelectedHostId] = useState<number | null>(null);
Expand Down Expand Up @@ -78,6 +81,11 @@ const MyHostPage = () => {
/>
))}
</div>
<div className="sticky w-full flex justify-end px-6 z-50">
<FloatingButton ariaLabel="사용법" onClick={() => window.open(HOST_MANUAL_URL, '_blank')} className='bottom-8'>
<img src={manualIcon} alt="사용법" className="w-full h-full" />
</FloatingButton>
</div>
</TicketHostLayout>
);
};
Expand Down
8 changes: 8 additions & 0 deletions src/shared/types/menuType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,19 @@ import SelectedHost from '../../../public/assets/menu/SelectedHost.svg';
import SelectedLogout from '../../../public/assets/menu/SelectedLogout.svg';
import SelectedSetting from '../../../public/assets/menu/SelectedSetting.svg';
import useAuthStore from '../../app/provider/authStore';
import Manual from '../../../public/assets/menu/manual.svg';
import SelectedManual from '../../../public/assets/menu/SelectedManual.svg';

export const USER_MANUAL_URL = 'https://namu00.notion.site/209eaffb9b0e803d9bc3da1fa0be5496';
export const HOST_MANUAL_URL = 'https://namu00.notion.site/209eaffb9b0e80caa0dae68c1e12ed0f';


export interface buttonData {
iconPath: string; // 아이콘 경로
hoverIconPath: string; // 호버 아이콘 경로
label: string; // 버튼 텍스트
path: string; // 경로
url?: string; // 외부 url
}

export const getButtonData = (): buttonData[] => {
Expand All @@ -25,6 +32,7 @@ export const getButtonData = (): buttonData[] => {
{ iconPath: Host, hoverIconPath: SelectedHost, label: '내 호스트', path: '/menu/myHost' },
{ iconPath: Event, hoverIconPath: SelectedEvent, label: '이벤트 주최하기', path: '/event-creation' },
{ iconPath: Setting, hoverIconPath: SelectedSetting, label: '마이페이지', path: '/menu/myPage' },
{ iconPath: Manual, hoverIconPath: SelectedManual, label: '사용법', path: '/menu/myTicket', url: USER_MANUAL_URL },
];

if (isLoggedIn) {
Expand Down
2 changes: 1 addition & 1 deletion src/shared/ui/EventCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const EventCard = ({
isDelete = false,
onDeleteSuccess,
onlineType,
aspectRatio = 'md:aspect-[3/4.3] sm:aspect-[3/4.5]'
aspectRatio = 'md:aspect-[3/4.3] sm:aspect-[3/5]'
}: EventCardProps) => {
const navigate = useNavigate();
const { pathname } = useLocation();
Expand Down
36 changes: 36 additions & 0 deletions src/shared/ui/FloatingButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { motion } from 'framer-motion';
import classNames from 'classnames';

interface FloatingButtonProps {
onClick: () => void;
children: React.ReactNode;
className?: string;
ariaLabel: string;
}

const FloatingButton = ({
onClick,
children,
className,
ariaLabel,
}: FloatingButtonProps) => {
return (
<motion.button
whileTap={{ scale: 0.9 }}
whileHover={{ scale: 1.05 }}
onClick={onClick}
aria-label={ariaLabel}
className={classNames(
'fixed right-100 ',
'z-50 flex items-center justify-center',
'rounded-full shadow-lg',
'w-12 h-12 sm:w-10 sm:h-10 lg:w-12 lg:h-12',
className,
)}
>
{children}
</motion.button>
);
};

export default FloatingButton;