diff --git a/src/_nav.tsx b/src/_nav.tsx index 4a360d3..9cb5e35 100644 --- a/src/_nav.tsx +++ b/src/_nav.tsx @@ -2,7 +2,6 @@ import React from 'react' import CIcon from '@coreui/icons-react' import { cilSpeedometer, - cilStar, } from '@coreui/icons' import { CNavGroup, CNavItem, CNavTitle } from '@coreui/react' @@ -21,37 +20,6 @@ const _nav = [ component: CNavTitle, name: 'Menu', }, - { - component: CNavTitle, - name: 'Extras', - }, - { - component: CNavGroup, - name: 'Pages', - icon: , - items: [ - { - component: CNavItem, - name: 'Login', - to: '/login', - }, - { - component: CNavItem, - name: 'Register', - to: '/register', - }, - { - component: CNavItem, - name: 'Error 404', - to: '/404', - }, - { - component: CNavItem, - name: 'Error 500', - to: '/500', - }, - ], - }, ] export default _nav diff --git a/src/assets/images/avatars/default.png b/src/assets/images/avatars/default.png new file mode 100644 index 0000000..d75072b Binary files /dev/null and b/src/assets/images/avatars/default.png differ diff --git a/src/components/AppFooter.tsx b/src/components/AppFooter.tsx index 24c8eff..55ebaac 100644 --- a/src/components/AppFooter.tsx +++ b/src/components/AppFooter.tsx @@ -5,14 +5,7 @@ const AppFooter = () => { return (
- - CoreUI - - © 2025 creativeLabs. -
- -
- Referrence : + CoreUI React Referrence : Demo diff --git a/src/components/AppHeader.tsx b/src/components/AppHeader.tsx index 87a884f..25bfb41 100644 --- a/src/components/AppHeader.tsx +++ b/src/components/AppHeader.tsx @@ -69,17 +69,6 @@ const AppHeader = () => { {member.memberId} )} - - - - - - - - - - - diff --git a/src/components/header/AppHeaderDropdown.tsx b/src/components/header/AppHeaderDropdown.tsx index e79124c..79ec160 100644 --- a/src/components/header/AppHeaderDropdown.tsx +++ b/src/components/header/AppHeaderDropdown.tsx @@ -1,7 +1,6 @@ -import React from 'react' +import React, { useState, useEffect } from 'react' import { CAvatar, - CBadge, CDropdown, CDropdownDivider, CDropdownHeader, @@ -10,24 +9,64 @@ import { CDropdownToggle, } from '@coreui/react' import { - cilBell, - cilCreditCard, - cilCommentSquare, - cilEnvelopeOpen, - cilFile, - cilLockLocked, - cilSettings, - cilTask, cilUser, cilAccountLogout, + cilClock, } from '@coreui/icons' import { useAuth } from 'src/hooks/useAuth' +import { getAccessTokenFromCookie, getRefreshTokenFromCookie, getUserFromToken } from 'src/axios/authService' import CIcon from '@coreui/icons-react' -import avatar8 from 'src/assets/images/avatars/8.jpg' +import avatar8 from 'src/assets/images/avatars/default.png' const AppHeaderDropdown = () => { - const { logout } = useAuth() + const { logout, state } = useAuth() + const [accessTokenExpiry, setAccessTokenExpiry] = useState('') + const [refreshTokenExpiry, setRefreshTokenExpiry] = useState('') + + useEffect(() => { + const formatExpiry = (diff: number): string => { + if (diff <= 0) return '만료됨' + const days = Math.floor(diff / (24 * 60 * 60 * 1000)) + const hours = Math.floor((diff % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000)) + const minutes = Math.floor((diff % (60 * 60 * 1000)) / 60000) + const seconds = Math.floor((diff % 60000) / 1000) + + if (days > 0) return `${days}일 ${hours}시간 후 만료` + if (hours > 0) return `${hours}시간 ${minutes}분 후 만료` + return `${minutes}분 ${seconds}초 후 만료` + } + + const updateExpiry = () => { + const now = new Date() + + // Access Token + const accessToken = getAccessTokenFromCookie() || localStorage.getItem('accessToken') + if (accessToken) { + const decoded = getUserFromToken(accessToken) + if (decoded?.exp) { + const diff = decoded.exp * 1000 - now.getTime() + setAccessTokenExpiry(formatExpiry(diff)) + } + } + + // Refresh Token + const refreshToken = getRefreshTokenFromCookie() || localStorage.getItem('refreshToken') + if (refreshToken) { + const decoded = getUserFromToken(refreshToken) + if (decoded?.exp) { + const diff = decoded.exp * 1000 - now.getTime() + setRefreshTokenExpiry(formatExpiry(diff)) + } + } else { + setRefreshTokenExpiry('HttpOnly (접근 불가)') + } + } + + updateExpiry() + const interval = setInterval(updateExpiry, 1000) + return () => clearInterval(interval) + }, []) return ( @@ -36,56 +75,21 @@ const AppHeaderDropdown = () => { Account - - - Updates - - 42 - - - - - Messages - - 42 - - - - - Tasks - - 42 - - - - - Comments - - 42 - - - Settings - + - Profile + ID: {state.member?.memberId || '-'} - - - Settings + + + 이름: {state.member?.memberName || '-'} - - - Payments - - 42 - + + + Access: {accessTokenExpiry} - - - Projects - - 42 - + + + Refresh: {refreshTokenExpiry} diff --git a/src/views/dashboard/Dashboard.tsx b/src/views/dashboard/Dashboard.tsx index 63d6f5a..9b21921 100644 --- a/src/views/dashboard/Dashboard.tsx +++ b/src/views/dashboard/Dashboard.tsx @@ -1,210 +1,10 @@ import React from 'react' -import classNames from 'classnames' - -import { - CAvatar, - CButton, - CButtonGroup, - CCard, - CCardBody, - CCardFooter, - CCardHeader, - CCol, - CProgress, - CRow, - CTable, - CTableBody, - CTableDataCell, - CTableHead, - CTableHeaderCell, - CTableRow, -} from '@coreui/react' -import CIcon from '@coreui/icons-react' -import { - cibCcAmex, - cibCcApplePay, - cibCcMastercard, - cibCcPaypal, - cibCcStripe, - cibCcVisa, - cibGoogle, - cibFacebook, - cibLinkedin, - cifBr, - cifEs, - cifFr, - cifIn, - cifPl, - cifUs, - cibTwitter, - cilCloudDownload, - cilPeople, - cilUser, - cilUserFemale, -} from '@coreui/icons' - -import avatar1 from 'src/assets/images/avatars/1.jpg' -import avatar2 from 'src/assets/images/avatars/2.jpg' -import avatar3 from 'src/assets/images/avatars/3.jpg' -import avatar4 from 'src/assets/images/avatars/4.jpg' -import avatar5 from 'src/assets/images/avatars/5.jpg' -import avatar6 from 'src/assets/images/avatars/6.jpg' - -import MainChart from 'src/views/dashboard/MainChart' const Dashboard = () => { - const tableExample = [ - { - avatar: { src: avatar1, status: 'success' }, - user: { - name: 'Yiorgos Avraamu', - new: true, - registered: 'Jan 1, 2023', - }, - country: { name: 'USA', flag: cifUs }, - usage: { - value: 50, - period: 'Jun 11, 2023 - Jul 10, 2023', - color: 'success', - }, - payment: { name: 'Mastercard', icon: cibCcMastercard }, - activity: '10 sec ago', - }, - { - avatar: { src: avatar2, status: 'danger' }, - user: { - name: 'Avram Tarasios', - new: false, - registered: 'Jan 1, 2023', - }, - country: { name: 'Brazil', flag: cifBr }, - usage: { - value: 22, - period: 'Jun 11, 2023 - Jul 10, 2023', - color: 'info', - }, - payment: { name: 'Visa', icon: cibCcVisa }, - activity: '5 minutes ago', - }, - { - avatar: { src: avatar3, status: 'warning' }, - user: { name: 'Quintin Ed', new: true, registered: 'Jan 1, 2023' }, - country: { name: 'India', flag: cifIn }, - usage: { - value: 74, - period: 'Jun 11, 2023 - Jul 10, 2023', - color: 'warning', - }, - payment: { name: 'Stripe', icon: cibCcStripe }, - activity: '1 hour ago', - }, - { - avatar: { src: avatar4, status: 'secondary' }, - user: { name: 'Enéas Kwadwo', new: true, registered: 'Jan 1, 2023' }, - country: { name: 'France', flag: cifFr }, - usage: { - value: 98, - period: 'Jun 11, 2023 - Jul 10, 2023', - color: 'danger', - }, - payment: { name: 'PayPal', icon: cibCcPaypal }, - activity: 'Last month', - }, - { - avatar: { src: avatar5, status: 'success' }, - user: { - name: 'Agapetus Tadeáš', - new: true, - registered: 'Jan 1, 2023', - }, - country: { name: 'Spain', flag: cifEs }, - usage: { - value: 22, - period: 'Jun 11, 2023 - Jul 10, 2023', - color: 'primary', - }, - payment: { name: 'Google Wallet', icon: cibCcApplePay }, - activity: 'Last week', - }, - { - avatar: { src: avatar6, status: 'danger' }, - user: { - name: 'Friderik Dávid', - new: true, - registered: 'Jan 1, 2023', - }, - country: { name: 'Poland', flag: cifPl }, - usage: { - value: 43, - period: 'Jun 11, 2023 - Jul 10, 2023', - color: 'success', - }, - payment: { name: 'Amex', icon: cibCcAmex }, - activity: 'Last week', - }, - ] - return ( - <> - - Traffic {' & '} Sales - - - - - - - - User - - Country - - Usage - - Payment Method - - Activity - - - - {tableExample.map((item, index) => ( - - - - - -
{item.user.name}
-
- {item.user.new ? 'New' : 'Recurring'} | Registered:{' '} - {item.user.registered} -
-
- - - - -
-
{item.usage.value}%
-
- {item.usage.period} -
-
- -
- - - - -
Last login
-
{item.activity}
-
-
- ))} -
-
-
-
- +
+

Welcome to Admin Sample

+
) }