feat. header 컴포넌트 반응형 제작
This commit is contained in:
180
layers/utils/formatUtil.ts
Normal file
180
layers/utils/formatUtil.ts
Normal file
@@ -0,0 +1,180 @@
|
||||
/**
|
||||
* 포맷 유틸리티 함수
|
||||
* @description 포맷 처리에 필요한 유틸리티 함수를 제공합니다.
|
||||
*/
|
||||
|
||||
/**
|
||||
* JWT 디코딩
|
||||
* @param base64EncodeVal JWT 인코딩 값
|
||||
* @returns JWT 디코딩 값
|
||||
*/
|
||||
export const csrFormatJWT = (base64EncodeVal: string) => {
|
||||
const decodeVal = JSON.parse(
|
||||
decodeURIComponent(
|
||||
window
|
||||
.atob(base64EncodeVal)
|
||||
.split('')
|
||||
.map(function (c) {
|
||||
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
|
||||
})
|
||||
.join('')
|
||||
)
|
||||
)
|
||||
|
||||
return decodeVal
|
||||
}
|
||||
|
||||
/**
|
||||
* 타임스탬프를 다양한 날짜 형식으로 변환합니다.
|
||||
* @param timestamp 타임스탬프 (밀리초 또는 초)
|
||||
* @param format 날짜 형식 ('YYYY-MM-DD', 'YYYY-MM-DD HH:mm:ss', 'MM/DD/YYYY', 'YYYY년 MM월 DD일' 등)
|
||||
* @param locale 로케일 (기본값: 'ko-KR')
|
||||
* @returns 포맷된 날짜 문자열
|
||||
*/
|
||||
export const formatTimestamp = (
|
||||
timestamp: number | string,
|
||||
format: string = 'YYYY.MM.DD',
|
||||
_locale: string = 'ko-KR'
|
||||
): string => {
|
||||
if (!timestamp) return ''
|
||||
|
||||
// 타임스탬프를 숫자로 변환
|
||||
let ts = typeof timestamp === 'string' ? parseInt(timestamp) : timestamp
|
||||
|
||||
// 초 단위인 경우 밀리초로 변환
|
||||
if (ts < 10000000000) {
|
||||
ts = ts * 1000
|
||||
}
|
||||
|
||||
const date = new Date(ts)
|
||||
|
||||
// 유효하지 않은 날짜인 경우 빈 문자열 반환
|
||||
if (isNaN(date.getTime())) {
|
||||
return ''
|
||||
}
|
||||
|
||||
// 미리 정의된 형식들
|
||||
const predefinedFormats: Record<string, string> = {
|
||||
'YYYY.MM.DD': date.toISOString().split('T')[0].replace(/-/g, '.'),
|
||||
'YYYY-MM-DD': date.toISOString().split('T')[0],
|
||||
'YYYY-MM-DD HH:mm': date.toISOString().replace('T', ' ').substring(0, 16),
|
||||
'YYYY-MM-DD HH:mm:ss': date.toISOString().replace('T', ' ').split('.')[0],
|
||||
'MM/DD/YYYY': date.toLocaleDateString('en-US'),
|
||||
'DD/MM/YYYY': date.toLocaleDateString('en-GB'),
|
||||
'YYYY년 MM월 DD일': date.toLocaleDateString('ko-KR', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
}),
|
||||
'MM월 DD일': date.toLocaleDateString('ko-KR', {
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
}),
|
||||
}
|
||||
|
||||
// 미리 정의된 형식이 있으면 사용
|
||||
if (predefinedFormats[format]) {
|
||||
return predefinedFormats[format]
|
||||
}
|
||||
|
||||
// 커스텀 형식 처리
|
||||
const year = date.getFullYear()
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(date.getDate()).padStart(2, '0')
|
||||
const hours = String(date.getHours()).padStart(2, '0')
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0')
|
||||
const seconds = String(date.getSeconds()).padStart(2, '0')
|
||||
|
||||
return format
|
||||
.replace('YYYY', String(year))
|
||||
.replace('MM', month)
|
||||
.replace('DD', day)
|
||||
.replace('HH', hours)
|
||||
.replace('mm', minutes)
|
||||
.replace('ss', seconds)
|
||||
}
|
||||
|
||||
/**
|
||||
* 타임스탬프를 상대적 시간으로 변환합니다 (예: "3일 전", "2시간 전")
|
||||
* @param timestamp 타임스탬프 (밀리초 또는 초)
|
||||
* @param locale 로케일 (기본값: 'ko-KR')
|
||||
* @returns 상대적 시간 문자열
|
||||
*/
|
||||
export const formatRelativeTime = (
|
||||
timestamp: number | string,
|
||||
locale: string = 'ko-KR'
|
||||
): string => {
|
||||
if (!timestamp) return ''
|
||||
|
||||
let ts = typeof timestamp === 'string' ? parseInt(timestamp) : timestamp
|
||||
if (ts < 10000000000) {
|
||||
ts = ts * 1000
|
||||
}
|
||||
|
||||
const date = new Date(ts)
|
||||
const now = new Date()
|
||||
const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000)
|
||||
|
||||
if (diffInSeconds < 60) {
|
||||
return locale === 'ko-KR' ? '방금 전' : 'just now'
|
||||
}
|
||||
|
||||
const diffInMinutes = Math.floor(diffInSeconds / 60)
|
||||
if (diffInMinutes < 60) {
|
||||
return locale === 'ko-KR'
|
||||
? `${diffInMinutes}분 전`
|
||||
: `${diffInMinutes} minutes ago`
|
||||
}
|
||||
|
||||
const diffInHours = Math.floor(diffInMinutes / 60)
|
||||
if (diffInHours < 24) {
|
||||
return locale === 'ko-KR'
|
||||
? `${diffInHours}시간 전`
|
||||
: `${diffInHours} hours ago`
|
||||
}
|
||||
|
||||
const diffInDays = Math.floor(diffInHours / 24)
|
||||
if (diffInDays < 30) {
|
||||
return locale === 'ko-KR' ? `${diffInDays}일 전` : `${diffInDays} days ago`
|
||||
}
|
||||
|
||||
const diffInMonths = Math.floor(diffInDays / 30)
|
||||
if (diffInMonths < 12) {
|
||||
return locale === 'ko-KR'
|
||||
? `${diffInMonths}개월 전`
|
||||
: `${diffInMonths} months ago`
|
||||
}
|
||||
|
||||
const diffInYears = Math.floor(diffInMonths / 12)
|
||||
return locale === 'ko-KR' ? `${diffInYears}년 전` : `${diffInYears} years ago`
|
||||
}
|
||||
|
||||
/**
|
||||
* 배열 또는 객체를 배열로 변환합니다.
|
||||
* @param value 변환할 값 (배열, 객체, 또는 undefined/null)
|
||||
* @returns 배열
|
||||
*/
|
||||
export const formatToArray = <T>(
|
||||
value: T[] | Record<string, T> | undefined | null
|
||||
): T[] => {
|
||||
if (!value) return []
|
||||
return Array.isArray(value) ? value : Object.values(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* URL 경로에서 로케일 접두사를 제거합니다.
|
||||
* @param path 경로 문자열
|
||||
* @returns 로케일 접두사가 제거된 경로
|
||||
*/
|
||||
export const formatPathWithoutLocale = (path: string): string => {
|
||||
return path.replace(/^\/[a-z]{2}(?=\/|$)/, '') || '/'
|
||||
}
|
||||
|
||||
/**
|
||||
* URL이 내부 링크인지 확인합니다.
|
||||
* @param url 확인할 URL
|
||||
* @returns 내부 링크 여부
|
||||
*/
|
||||
export const isInternalUrl = (url?: string): boolean => {
|
||||
return !!url && !url.startsWith('http')
|
||||
}
|
||||
Reference in New Issue
Block a user