Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 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
13 changes: 13 additions & 0 deletions public/assets/dashboard/menu/QR(black).svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions public/assets/dashboard/menu/QR(pink).svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 5 additions & 1 deletion src/features/event/ui/EventFunnel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ const EventFunnel = ({ onNext, onPrev, Funnel, Step, currentStep }: EventFunnelI
setHostState(initialHostState);
handleNext(String(currentStep - 1));
},
onError: (error: any) => {
const message = error?.message || '호스트 생성에 실패했습니다. 다시 시도해주세요.';
alert(message);
},
Comment thread
hyeeuncho marked this conversation as resolved.
});
};

Expand All @@ -56,7 +60,7 @@ const EventFunnel = ({ onNext, onPrev, Funnel, Step, currentStep }: EventFunnelI
<EventRegisterLayout
title="이벤트를 호스팅할 채널을 선택해주세요"
onNext={() => handleNext(String(currentStep + 2))}
onPrev={() => navigate(-1)}
onPrev={() => navigate('/')}
requireValidation={true}
>
<HostSelectionPage onNext={handleNext} currentStep={currentStep} />
Expand Down
1 change: 1 addition & 0 deletions src/features/home/ui/EventSliderSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ const EventSliderSection = ({ title, events }: EventSliderSectionProps) => {
eventDate={event.startDate}
location={event.address}
hashtags={event.hashtags}
onlineType={event.onlineType}
onClick={() => navigate(`/event-details/${event.id}`)}
/>
</div>
Expand Down
6 changes: 3 additions & 3 deletions src/features/join/hooks/useUserHook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ export const useUserInfo = (enabled: boolean = true) => {
export const useUserUpdate = () => {
return useMutation<UserInfoResponse, Error, UserInfoRequest>({
mutationFn: updateUser,
onError: (error) => {
alert(error.message);
}
Comment thread
hyeeuncho marked this conversation as resolved.
});
};

export const useAgreeTerms = () => {
return useMutation({
mutationFn: agreeTerms,
onSuccess: () => {
alert('이용약관 동의 완료');
},
onError: (error) => {
alert('동의 처리 실패');
console.error('이용약관 동의 실패', error);
Expand Down
17 changes: 3 additions & 14 deletions src/features/ticket/ui/QrScanner.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useEffect, useRef, useState } from "react";
import QrScanner from "qr-scanner";
import { useTicketQrCodeValidate } from "../hooks/useOrderHook";
import Button from "../../../../design-system/ui/Button";

const QrScannerComponent = () => {
const videoRef = useRef<HTMLVideoElement>(null);
Expand Down Expand Up @@ -53,7 +54,6 @@ const QrScannerComponent = () => {
};

const checkInApiCall = async (qrData: string) => {
console.log("스캔된 QR 데이터:", qrData);
try {
const params = new URLSearchParams(qrData.replace(/-/g, '='));
const orderIdStr = params.get('orderId');
Expand All @@ -72,24 +72,13 @@ const QrScannerComponent = () => {

return (
<div className="p-4">
<h2 className="text-xl font-bold mb-2">QR 코드 스캔</h2>
<video
ref={videoRef}
className="border rounded w-full max-w-md"
style={{ aspectRatio: "4 / 3" }}
style={{ aspectRatio: "3 / 4" }}
/>
{!isScanning && (
<button
onClick={handleStartScan}
className="mt-4 px-4 py-2 bg-blue-600 text-white rounded"
>
스캔 시작
</button>
)}
{scanResult && (
<p className="mt-4 text-green-700 font-semibold">
스캔 결과: {scanResult}
</p>
<Button label="스캔하기" onClick={handleStartScan} className="w-full h-12 rounded-full mt-10 px-4 py-2" />
)}
</div>
);
Expand Down
14 changes: 10 additions & 4 deletions src/pages/dashboard/ui/ticket/CheckInPage.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import QrScannerComponent from "../../../../features/ticket/ui/QrScanner";
import DashboardLayout from "../../../../shared/ui/backgrounds/DashboardLayout";

const CheckInPage = () => {
return (
<div className="max-w-screen-md mx-auto">
<h1 className="text-2xl font-bold mb-4">체크인 스캐너</h1>
<QrScannerComponent />
</div>
<DashboardLayout centerContent="WOOACON 2024">
<div className='flex flex-col gap-2 mt-8 px-7'>
<h1 className="w-full text-center font-bold text-xl">QR 코드 스캔</h1>
<div className="max-w-screen-md mx-auto">
<QrScannerComponent />
</div>
</div>
</DashboardLayout>
Comment thread
hyeeuncho marked this conversation as resolved.
Outdated

);
};

Expand Down
14 changes: 7 additions & 7 deletions src/pages/event/ui/AllEventsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useNavigate } from 'react-router-dom';
import useAuthStore from '../../../app/provider/authStore';
import { AnimatePresence } from 'framer-motion';
import LoginModal from '../../../widgets/main/ui/LoginModal';
import ProfileCircle from '../../../../design-system/ui/Profile';

const AllEventsPage = () => {
const navigater = useNavigate();
Expand All @@ -21,19 +22,18 @@ const AllEventsPage = () => {
iconPath={<img src={searchIcon} alt="searchIcon" />}
onClick={() => navigater('/search')}
onChange={() => {}}
placeholder="입력해주세요"
placeholder="검색어를 입력해주세요"
/>
}
leftButtonClassName="sm:text-lg md:text-xl lg:text-2xl font-extrabold font-nexon"
leftButtonClick={() => navigater('/')}
leftButtonLabel="같이가요"
rightContent={
<SecondaryButton
size="large"
color="black"
label={isLoggedIn ? `${name}님` : '로그인'}
onClick={isLoggedIn ? closeModal : openModal}
/>
isLoggedIn ? (
<ProfileCircle profile="userProfile" name={name?.slice(1, 3) || ''} className="w-11 h-11 text-15" />
) : (
<SecondaryButton size="large" color="black" label="로그인" onClick={openModal} />
)
}
/>
<AnimatePresence>{isModalOpen && <LoginModal onClose={closeModal} />}</AnimatePresence>
Expand Down
39 changes: 21 additions & 18 deletions src/pages/event/ui/EventDetailsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,24 +136,27 @@ const EventDetailsPage = () => {
<h2 className="font-bold text-xl">티켓 옵션</h2>
<TicketInfo eventId={event.result.id} />

<div className="flex flex-col gap-2">
<h2 className="font-bold text-xl">관련 링크</h2>
<div className="flex flex-col gap-3 mb-4">
{event.result.referenceLinks.map((link: { title: string; url: string }, index: number) => (
<div key={index} className="flex items-center gap-2">
<img src={linkIcon} alt="링크 이모지" />
<a
href={link.url}
target="_blank"
rel="noopener noreferrer"
className="text-blue-500 underline"
>
{link.title}
</a>
</div>
))}
</div>
</div>
{event.result.referenceLinks && event.result.referenceLinks.length > 0 && (
<div className="flex flex-col gap-2">
<h2 className="font-bold text-xl">관련 링크</h2>
<div className="flex flex-col gap-3 mb-4">
{event.result.referenceLinks.map((link: { title: string; url: string }, index: number) => (
<div key={index} className="flex items-center gap-2">
<img src={linkIcon} alt="링크 이모지" />
<a
href={link.url}
target="_blank"
rel="noopener noreferrer"
className="text-blue-500 underline"
>
{link.title}
</a>
</div>
))}
</div>
</div>
)}

</div>
</>
) : (
Expand Down
2 changes: 1 addition & 1 deletion src/pages/home/ui/MainPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const MainPage = () => {
iconPath={<img src={searchIcon} alt="Search" />}
onClick={() => navigate('/search')}
onChange={() => {}}
placeholder="입력해주세요"
placeholder="검색어를 입력해주세요"
/>
}
leftButtonClassName="sm:text-lg md:text-xl lg:text-2xl font-extrabold font-nexon"
Expand Down
19 changes: 2 additions & 17 deletions src/pages/join/AgreementPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,13 @@ import Button from '../../../design-system/ui/Button';
import AgreementList from '../../features/join/ui/AgreementList';
import { useAgreementStore } from '../../features/join/model/agreementStore';
import { useNavigate } from 'react-router-dom';
import { useAgreeTerms } from '../../features/join/hooks/useUserHook';
import { TermsAgreementRequest } from '../../features/join/model/userInformation';

const AgreementPage: React.FC = () => {
const { isAllRequiredAgreed, getAgreementStates } = useAgreementStore();
const { isAllRequiredAgreed } = useAgreementStore();
const navigate = useNavigate();
const { mutate:agreeTerms } = useAgreeTerms();

const handleAgree = () => {
const states = getAgreementStates();
const agreementData: TermsAgreementRequest = {
serviceAgreed: states.serviceAgreed,
privacyPolicyAgree: states.privacyPolicyAgree,
personalInfoUsageAgreed: states.personalInfoUsageAgreed,
marketingAgreed: states.marketingAgreed,
};

agreeTerms(agreementData, {
onSuccess: () => {
navigate('/join/info-input');
},
});
navigate('/join/info-input');
};

return (
Expand Down
29 changes: 24 additions & 5 deletions src/pages/join/InfoInputPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import Header from '../../../design-system/ui/Header';
import Button from '../../../design-system/ui/Button';
import UnderlineTextField from '../../../design-system/ui/textFields/UnderlineTextField';
import { FormData, zodValidation } from '../../shared/lib/formValidation';
import { useUserInfo, useUserUpdate } from '../../features/join/hooks/useUserHook';
import { useAgreeTerms, useUserInfo, useUserUpdate } from '../../features/join/hooks/useUserHook';
import useAuthStore from '../../app/provider/authStore';
import { formatPhoneNumber } from '../../shared/utils/phoneFormatter';
import { useAgreementStore } from '../../features/join/model/agreementStore';

const InfoInputPage = () => {
const { data, isLoading } = useUserInfo();
Expand All @@ -32,24 +33,42 @@ const InfoInputPage = () => {
const navigate = useNavigate();

const phoneValue = watch('phone');
const { getAgreementStates } = useAgreementStore();
const { mutate: agreeTerms } = useAgreeTerms();

const handlePhoneChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const formatted = formatPhoneNumber(e.target.value);
setValue('phone', formatted, { shouldValidate: true });
};

const onSubmit: SubmitHandler<FormData> = formData => {
const agreementStates = getAgreementStates();
const updatedData = {
name: data?.name || '',
email: data?.email || '',
phoneNumber: formData.phone,
};
updateUser(updatedData, {
onSuccess: () => {
Comment thread
hyeeuncho marked this conversation as resolved.
login();
setName(data?.name || '사용자');
alert('정보가 성공적으로 업데이트되었습니다.');
navigate('/');
agreeTerms(
{
serviceAgreed: agreementStates.serviceAgreed,
privacyPolicyAgree: agreementStates.privacyPolicyAgree,
personalInfoUsageAgreed: agreementStates.personalInfoUsageAgreed,
marketingAgreed: agreementStates.marketingAgreed,
},
{
onSuccess: () => {
login();
setName(formData.name);
alert('회원가입이 완료되었습니다.');
navigate('/');
},
onError: () => {
alert('약관 동의 처리에 실패했습니다.');
},
}
);
},
onError: err => {
alert('정보 업데이트에 실패했습니다. 다시 시도해주세요.');
Expand Down
Loading