| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- 'use client';
- import { useEffect, useState, useCallback } from 'react';
- import { createPortal } from 'react-dom';
- import { CryptoProvider, useCryptoContext } from '@/contexts/cryptoProvider';
- import CryptoDashboard from './CryptoDashboard';
- import CryptoSidebar from './CryptoSidebar';
- import MobileCoinList from './MobileCoinList';
- import PopupModal from '@/app/component/PopupModal';
- import Styles from '@/app/styles/common.module.scss';
- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
- import { faChevronLeft } from '@fortawesome/free-solid-svg-icons';
- import type { TickerRestData } from '@/types/crypto';
- import './mobile-coin-list.scss';
- type Props = {
- initialTickers: TickerRestData[];
- };
- function MobileBackButton({ onBack }: { onBack: () => void }) {
- const { selectedMarket, tickerMeta } = useCryptoContext();
- const meta = tickerMeta.get(selectedMarket);
- const displayName = meta?.korName ?? selectedMarket.split('-')[1] ?? selectedMarket;
- return (
- <div className='mobile-back-bar'>
- <button type='button' onClick={onBack}>
- <FontAwesomeIcon icon={faChevronLeft} />
- {displayName}
- </button>
- </div>
- );
- }
- export default function CryptoPageContent({ initialTickers }: Props) {
- const [containerEl, setContainerEl] = useState<HTMLElement | null>(null);
- const [isMobile, setIsMobile] = useState(false);
- const [mobileView, setMobileView] = useState<'list' | 'detail'>('list');
- useEffect(() => {
- setContainerEl(document.getElementById('container'));
- return () => setContainerEl(null);
- }, []);
- useEffect(() => {
- const mq = window.matchMedia('(max-width: 1125px)');
- setIsMobile(mq.matches);
- const handler = (e: MediaQueryListEvent) => {
- setIsMobile(e.matches);
- if (!e.matches) setMobileView('list');
- };
- mq.addEventListener('change', handler);
- return () => mq.removeEventListener('change', handler);
- }, []);
- // 하단 탭바 "코인" 클릭 시 목록으로 복귀
- useEffect(() => {
- const handler = () => setMobileView('list');
- window.addEventListener('crypto:showList', handler);
- return () => window.removeEventListener('crypto:showList', handler);
- }, []);
- const handleSelectCoin = useCallback(() => {
- setMobileView('detail');
- }, []);
- const handleBack = useCallback(() => {
- setMobileView('list');
- }, []);
- return (
- <CryptoProvider>
- <PopupModal position='main' />
- {isMobile ? (
- mobileView === 'list' ? (
- <MobileCoinList
- initialTickers={initialTickers}
- onSelectCoin={handleSelectCoin}
- />
- ) : (
- <>
- <MobileBackButton onBack={handleBack} />
- <CryptoDashboard />
- </>
- )
- ) : (
- <CryptoDashboard />
- )}
- {!isMobile && containerEl && createPortal(
- <aside id='aside' className={Styles.aside}>
- <CryptoSidebar initialTickers={initialTickers} />
- </aside>,
- containerEl
- )}
- </CryptoProvider>
- );
- }
|