1- import { useState , useEffect } from 'react' ;
1+ import { useState , useEffect , useRef } from 'react' ;
22import MonthlyChartVoteList from '@/components/modalContent/MonthlyChartVoteList' ;
3- import { getLists } from '@/apis/monthlyChartApi' ;
3+ import { getLists , postVotes } from '@/apis/monthlyChartApi' ;
44import PrimaryButton from '@/components/PrimaryButton' ;
5+ import { spendCredits } from '../../utils/creditStorage' ;
56
6- const MonthlyChartVoteModal = ( { gender } ) => {
7+ const MonthlyChartVoteModal = ( { gender, onClickVoteCredit , closeModal } ) => {
78 const [ cursor , setCursor ] = useState ( 0 ) ;
89 const [ idolData , setIdolData ] = useState ( [ ] ) ;
910 const [ loading , setLoading ] = useState ( false ) ;
1011 const [ selectedIdol , setSelectedIdol ] = useState ( 0 ) ;
12+ const [ isMobile , setIsMobile ] = useState ( false ) ;
13+ const observerRef = useRef ( ) ;
1114
1215 const loadIdolData = async ( ) => {
1316 setLoading ( true ) ;
@@ -26,11 +29,21 @@ const MonthlyChartVoteModal = ({ gender }) => {
2629 }
2730 } ;
2831
29- const loadMoreData = ( ) => {
30- if ( cursor === null ) {
31- alert ( '불러올 데이터가 없습니다.' ) ;
32+ const handleVoteClick = async ( ) => {
33+ const result = spendCredits ( 1000 ) ;
34+ if ( result === 'NOT-ENOUGH' ) {
35+ alert ( '앗! 투표하기 위한 크레딧이 부족해요' ) ;
3236 } else {
33- loadIdolData ( ) ;
37+ try {
38+ const voteResult = await postVotes ( selectedIdol ) ;
39+ alert ( '투표 완료!' ) ;
40+
41+ if ( onClickVoteCredit ) onClickVoteCredit ( ) ;
42+ closeModal ( ) ;
43+ } catch ( error ) {
44+ console . error ( error ) ;
45+ alert ( '투표에 실패했습니다. 다시 시도해 주세요.' ) ;
46+ }
3447 }
3548 } ;
3649
@@ -40,22 +53,58 @@ const MonthlyChartVoteModal = ({ gender }) => {
4053 loadIdolData ( ) ;
4154 } , [ gender ] ) ;
4255
56+ useEffect ( ( ) => {
57+ const handleResize = ( ) => {
58+ setIsMobile ( window . innerWidth < 768 ) ;
59+ } ;
60+
61+ window . addEventListener ( 'resize' , handleResize ) ;
62+ handleResize ( ) ;
63+ return ( ) => window . removeEventListener ( 'resize' , handleResize ) ;
64+ } , [ ] ) ;
65+
66+ useEffect ( ( ) => {
67+ if ( cursor === null ) return ;
68+
69+ const observer = new IntersectionObserver (
70+ ( entries ) => {
71+ if ( entries [ 0 ] . isIntersecting ) loadIdolData ( ) ;
72+ } ,
73+ { threshold : 0.2 }
74+ ) ;
75+ if ( observerRef . current ) observer . observe ( observerRef . current ) ;
76+ return ( ) => observer . disconnect ( ) ;
77+ } , [ cursor ] ) ;
78+
4379 return (
44- < div className = "w-[calc(100%-48px)] h-[693px] tablet:w-[525px] tablet:h-[693px] pc:w-[525px] pc:h-[693px] overflow-y-auto" >
80+ < div
81+ className = { `relative overflow-hidden ${ isMobile ? 'w-[calc(100%-24px)] h-full' : 'w-[525px] h-[693px]' } ` }
82+ >
4583 { loading ? (
4684 < div className = "text-center text-white" > 로딩 중입니다...</ div >
4785 ) : (
4886 < MonthlyChartVoteList
4987 idols = { idolData }
5088 selectedIdol = { selectedIdol }
5189 setSelectedIdol = { setSelectedIdol }
52- />
90+ >
91+ < div
92+ className = "w-full h-[40px]"
93+ ref = { cursor !== null ? observerRef : null }
94+ > </ div >
95+ </ MonthlyChartVoteList >
5396 ) }
54- < div className = "fixed bottom-0 w-[calc(100%-48px)] h-[106px] text-white leading-[26px] bg-midnightBlack/80 tablet:w-[525px] pc:w-[525px] tablet:bg-transparent pc:bg-transparent" >
55- < PrimaryButton className = "w-full h-[42px] font-bold text-[14px] font-pretendard" >
97+ < div
98+ style = { { width : isMobile ? 'calc(100vw - 68px)' : '525px' } }
99+ className = { `absolute text-white leading-[26px] ${ isMobile ? 'bottom-[64px] h-[112px] bg-midnightBlack' : 'bottom-0 h-[72px] bg-deepCharcoal' } ` }
100+ >
101+ < PrimaryButton
102+ onClickFunc = { handleVoteClick }
103+ className = "w-full h-[42px] font-bold text-[14px] font-pretendard"
104+ >
56105 투표하기
57106 </ PrimaryButton >
58- < p className = "font-medium text-[12px] text-center" >
107+ < p className = "font-medium text-[12px] text-center mt-[8px] tablet:mt-[12px] pc:mt-[12px] " >
59108 투표하는 데< span className = " text-coralRed" > 1000 크레딧</ span > 이
60109 소모됩니다.
61110 </ p >
0 commit comments