X 날짜 포맷팅을 dayjs 기반 유틸리티로 통합
- formatXDateTime 함수를 utils/date.js로 이동 - PC/모바일 XSection에서 공통 유틸리티 사용 - 사용하지 않는 closeLightbox 변수 제거 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
67e9992cf1
commit
e1a07f4849
3 changed files with 28 additions and 58 deletions
|
|
@ -5,6 +5,7 @@ import { motion, AnimatePresence } from 'framer-motion';
|
||||||
import { Calendar, Clock, ChevronLeft, Check, Link2, MapPin, Navigation, ExternalLink, X, ChevronRight } from 'lucide-react';
|
import { Calendar, Clock, ChevronLeft, Check, Link2, MapPin, Navigation, ExternalLink, X, ChevronRight } from 'lucide-react';
|
||||||
import Linkify from 'react-linkify';
|
import Linkify from 'react-linkify';
|
||||||
import { getSchedule } from '../../../api/public/schedules';
|
import { getSchedule } from '../../../api/public/schedules';
|
||||||
|
import { formatXDateTime } from '../../../utils/date';
|
||||||
import '../../../mobile.css';
|
import '../../../mobile.css';
|
||||||
|
|
||||||
// 카카오맵 SDK 키
|
// 카카오맵 SDK 키
|
||||||
|
|
@ -177,26 +178,6 @@ const extractXUsername = (url) => {
|
||||||
return match ? match[1] : null;
|
return match ? match[1] : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
// X용 날짜/시간 포맷팅 (오후 2:30 · 2026년 1월 15일)
|
|
||||||
const formatXDateTime = (dateStr, timeStr) => {
|
|
||||||
if (!dateStr) return '';
|
|
||||||
const date = new Date(dateStr);
|
|
||||||
const year = date.getFullYear();
|
|
||||||
const month = date.getMonth() + 1;
|
|
||||||
const day = date.getDate();
|
|
||||||
|
|
||||||
let result = `${year}년 ${month}월 ${day}일`;
|
|
||||||
|
|
||||||
if (timeStr) {
|
|
||||||
const [hours, minutes] = timeStr.split(':').map(Number);
|
|
||||||
const period = hours < 12 ? '오전' : '오후';
|
|
||||||
const hour12 = hours === 0 ? 12 : hours > 12 ? hours - 12 : hours;
|
|
||||||
result = `${period} ${hour12}:${String(minutes).padStart(2, '0')} · ${result}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 유튜브 섹션 컴포넌트
|
// 유튜브 섹션 컴포넌트
|
||||||
function YoutubeSection({ schedule }) {
|
function YoutubeSection({ schedule }) {
|
||||||
const videoId = extractYoutubeVideoId(schedule.source?.url);
|
const videoId = extractYoutubeVideoId(schedule.source?.url);
|
||||||
|
|
@ -367,21 +348,6 @@ function XSection({ schedule }) {
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
|
|
||||||
// datetime 포맷팅
|
|
||||||
const formatDateTime = (datetime) => {
|
|
||||||
if (!datetime) return '';
|
|
||||||
const [datePart, timePart] = datetime.split(' ');
|
|
||||||
const [year, month, day] = datePart.split('-').map(Number);
|
|
||||||
let timeStr = '';
|
|
||||||
if (timePart) {
|
|
||||||
const [hour, minute] = timePart.split(':').map(Number);
|
|
||||||
const period = hour >= 12 ? '오후' : '오전';
|
|
||||||
const hour12 = hour > 12 ? hour - 12 : hour === 0 ? 12 : hour;
|
|
||||||
timeStr = `${period} ${hour12}:${String(minute).padStart(2, '0')} · `;
|
|
||||||
}
|
|
||||||
return `${timeStr}${year}년 ${month}월 ${day}일`;
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<motion.div
|
<motion.div
|
||||||
|
|
@ -463,7 +429,7 @@ function XSection({ schedule }) {
|
||||||
{/* 날짜/시간 */}
|
{/* 날짜/시간 */}
|
||||||
<div className="px-4 py-3 border-t border-gray-100">
|
<div className="px-4 py-3 border-t border-gray-100">
|
||||||
<span className="text-gray-500 text-sm">
|
<span className="text-gray-500 text-sm">
|
||||||
{formatDateTime(schedule.datetime)}
|
{formatXDateTime(schedule.datetime)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,24 +3,7 @@ import { motion } from 'framer-motion';
|
||||||
import Linkify from 'react-linkify';
|
import Linkify from 'react-linkify';
|
||||||
import { decodeHtmlEntities } from './utils';
|
import { decodeHtmlEntities } from './utils';
|
||||||
import Lightbox from '../../../../components/common/Lightbox';
|
import Lightbox from '../../../../components/common/Lightbox';
|
||||||
|
import { formatXDateTime } from '../../../../utils/date';
|
||||||
// datetime 포맷팅 (2026-01-18 19:00 → 오후 7:00 · 2026년 1월 18일)
|
|
||||||
const formatXDateTime = (datetime) => {
|
|
||||||
if (!datetime) return '';
|
|
||||||
|
|
||||||
const [datePart, timePart] = datetime.split(' ');
|
|
||||||
const [year, month, day] = datePart.split('-').map(Number);
|
|
||||||
|
|
||||||
let timeStr = '';
|
|
||||||
if (timePart) {
|
|
||||||
const [hour, minute] = timePart.split(':').map(Number);
|
|
||||||
const period = hour >= 12 ? '오후' : '오전';
|
|
||||||
const hour12 = hour > 12 ? hour - 12 : hour === 0 ? 12 : hour;
|
|
||||||
timeStr = `${period} ${hour12}:${String(minute).padStart(2, '0')} · `;
|
|
||||||
}
|
|
||||||
|
|
||||||
return `${timeStr}${year}년 ${month}월 ${day}일`;
|
|
||||||
};
|
|
||||||
|
|
||||||
// X(트위터) 섹션 컴포넌트
|
// X(트위터) 섹션 컴포넌트
|
||||||
function XSection({ schedule }) {
|
function XSection({ schedule }) {
|
||||||
|
|
@ -39,10 +22,6 @@ function XSection({ schedule }) {
|
||||||
window.history.pushState({ lightbox: true }, '');
|
window.history.pushState({ lightbox: true }, '');
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const closeLightbox = useCallback(() => {
|
|
||||||
setLightboxOpen(false);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// 뒤로가기 처리
|
// 뒤로가기 처리
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handlePopState = () => {
|
const handlePopState = () => {
|
||||||
|
|
|
||||||
|
|
@ -77,5 +77,30 @@ export const isToday = (date) => {
|
||||||
return isSameDay(date, dayjs());
|
return isSameDay(date, dayjs());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* X(트위터) 스타일 날짜/시간 포맷팅
|
||||||
|
* 입력: "2026-01-18 19:00" 또는 "2026-01-18"
|
||||||
|
* 출력: "오후 7:00 · 2026년 1월 18일" 또는 "2026년 1월 18일"
|
||||||
|
* @param {string} datetime - 날짜/시간 문자열
|
||||||
|
* @returns {string} 포맷된 문자열
|
||||||
|
*/
|
||||||
|
export const formatXDateTime = (datetime) => {
|
||||||
|
if (!datetime) return '';
|
||||||
|
|
||||||
|
const d = dayjs(datetime).tz(KST);
|
||||||
|
const datePart = d.format('YYYY년 M월 D일');
|
||||||
|
|
||||||
|
// 시간이 포함된 경우
|
||||||
|
if (datetime.includes(' ') || datetime.includes('T')) {
|
||||||
|
const hour = d.hour();
|
||||||
|
const minute = d.minute();
|
||||||
|
const period = hour >= 12 ? '오후' : '오전';
|
||||||
|
const hour12 = hour > 12 ? hour - 12 : hour === 0 ? 12 : hour;
|
||||||
|
return `${period} ${hour12}:${String(minute).padStart(2, '0')} · ${datePart}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return datePart;
|
||||||
|
};
|
||||||
|
|
||||||
// dayjs 인스턴스도 export (고급 사용용)
|
// dayjs 인스턴스도 export (고급 사용용)
|
||||||
export { dayjs };
|
export { dayjs };
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue