미사용 요소 제거

This commit is contained in:
2026-01-23 09:42:13 +09:00
parent 1f2c39869c
commit f18972f080
6 changed files with 66 additions and 312 deletions

View File

@@ -2,7 +2,6 @@ import React from 'react'
import CIcon from '@coreui/icons-react' import CIcon from '@coreui/icons-react'
import { import {
cilSpeedometer, cilSpeedometer,
cilStar,
} from '@coreui/icons' } from '@coreui/icons'
import { CNavGroup, CNavItem, CNavTitle } from '@coreui/react' import { CNavGroup, CNavItem, CNavTitle } from '@coreui/react'
@@ -21,37 +20,6 @@ const _nav = [
component: CNavTitle, component: CNavTitle,
name: 'Menu', name: 'Menu',
}, },
{
component: CNavTitle,
name: 'Extras',
},
{
component: CNavGroup,
name: 'Pages',
icon: <CIcon icon={cilStar} customClassName="nav-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 export default _nav

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -5,14 +5,7 @@ const AppFooter = () => {
return ( return (
<CFooter className="px-4"> <CFooter className="px-4">
<div> <div>
<a href="https://coreui.io" target="_blank" rel="noopener noreferrer"> <span className="m-2">CoreUI React Referrence :</span>
CoreUI
</a>
<span className="ms-1">&copy; 2025 creativeLabs.</span>
</div>
<div>
<span className="m-2">Referrence :</span>
<a href="https://coreui.io/demos/react/5.5/free/?theme=light#/dashboard" target="_blank" rel="noopener noreferrer"> <a href="https://coreui.io/demos/react/5.5/free/?theme=light#/dashboard" target="_blank" rel="noopener noreferrer">
Demo Demo
</a> </a>

View File

@@ -69,17 +69,6 @@ const AppHeader = () => {
{member.memberId} {member.memberId}
</span> </span>
)} )}
<CIcon icon={cilBell} size="lg" />
</CNavLink>
</CNavItem>
<CNavItem>
<CNavLink href="#">
<CIcon icon={cilList} size="lg" />
</CNavLink>
</CNavItem>
<CNavItem>
<CNavLink href="#">
<CIcon icon={cilEnvelopeOpen} size="lg" />
</CNavLink> </CNavLink>
</CNavItem> </CNavItem>
</CHeaderNav> </CHeaderNav>

View File

@@ -1,7 +1,6 @@
import React from 'react' import React, { useState, useEffect } from 'react'
import { import {
CAvatar, CAvatar,
CBadge,
CDropdown, CDropdown,
CDropdownDivider, CDropdownDivider,
CDropdownHeader, CDropdownHeader,
@@ -10,24 +9,64 @@ import {
CDropdownToggle, CDropdownToggle,
} from '@coreui/react' } from '@coreui/react'
import { import {
cilBell,
cilCreditCard,
cilCommentSquare,
cilEnvelopeOpen,
cilFile,
cilLockLocked,
cilSettings,
cilTask,
cilUser, cilUser,
cilAccountLogout, cilAccountLogout,
cilClock,
} from '@coreui/icons' } from '@coreui/icons'
import { useAuth } from 'src/hooks/useAuth' import { useAuth } from 'src/hooks/useAuth'
import { getAccessTokenFromCookie, getRefreshTokenFromCookie, getUserFromToken } from 'src/axios/authService'
import CIcon from '@coreui/icons-react' 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 AppHeaderDropdown = () => {
const { logout } = useAuth() const { logout, state } = useAuth()
const [accessTokenExpiry, setAccessTokenExpiry] = useState<string>('')
const [refreshTokenExpiry, setRefreshTokenExpiry] = useState<string>('')
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 ( return (
<CDropdown variant="nav-item"> <CDropdown variant="nav-item">
@@ -36,56 +75,21 @@ const AppHeaderDropdown = () => {
</CDropdownToggle> </CDropdownToggle>
<CDropdownMenu className="pt-0"> <CDropdownMenu className="pt-0">
<CDropdownHeader className="bg-body-secondary fw-semibold mb-2">Account</CDropdownHeader> <CDropdownHeader className="bg-body-secondary fw-semibold mb-2">Account</CDropdownHeader>
<CDropdownItem href="#"> <CDropdownItem className="disabled">
<CIcon icon={cilBell} className="me-2" />
Updates
<CBadge color="info" className="ms-2">
42
</CBadge>
</CDropdownItem>
<CDropdownItem href="#">
<CIcon icon={cilEnvelopeOpen} className="me-2" />
Messages
<CBadge color="success" className="ms-2">
42
</CBadge>
</CDropdownItem>
<CDropdownItem href="#">
<CIcon icon={cilTask} className="me-2" />
Tasks
<CBadge color="danger" className="ms-2">
42
</CBadge>
</CDropdownItem>
<CDropdownItem href="#">
<CIcon icon={cilCommentSquare} className="me-2" />
Comments
<CBadge color="warning" className="ms-2">
42
</CBadge>
</CDropdownItem>
<CDropdownHeader className="bg-body-secondary fw-semibold my-2">Settings</CDropdownHeader>
<CDropdownItem href="#">
<CIcon icon={cilUser} className="me-2" /> <CIcon icon={cilUser} className="me-2" />
Profile ID: {state.member?.memberId || '-'}
</CDropdownItem> </CDropdownItem>
<CDropdownItem href="#"> <CDropdownItem className="disabled">
<CIcon icon={cilSettings} className="me-2" /> <CIcon icon={cilUser} className="me-2" />
Settings : {state.member?.memberName || '-'}
</CDropdownItem> </CDropdownItem>
<CDropdownItem href="#"> <CDropdownItem className="disabled">
<CIcon icon={cilCreditCard} className="me-2" /> <CIcon icon={cilClock} className="me-2" />
Payments Access: {accessTokenExpiry}
<CBadge color="secondary" className="ms-2">
42
</CBadge>
</CDropdownItem> </CDropdownItem>
<CDropdownItem href="#"> <CDropdownItem className="disabled">
<CIcon icon={cilFile} className="me-2" /> <CIcon icon={cilClock} className="me-2" />
Projects Refresh: {refreshTokenExpiry}
<CBadge color="primary" className="ms-2">
42
</CBadge>
</CDropdownItem> </CDropdownItem>
<CDropdownDivider /> <CDropdownDivider />
<CDropdownItem onClick={logout} style={{ cursor: 'pointer' }}> <CDropdownItem onClick={logout} style={{ cursor: 'pointer' }}>

View File

@@ -1,210 +1,10 @@
import React from 'react' 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 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 ( return (
<> <div className="d-flex justify-content-center align-items-center" style={{ minHeight: '60vh' }}>
<CCard className="mb-4"> <h1 className="text-body-secondary">Welcome to Admin Sample</h1>
<CCardHeader>Traffic {' & '} Sales</CCardHeader>
<CCardBody>
<CTable align="middle" className="mb-0 border" hover responsive>
<CTableHead className="text-nowrap">
<CTableRow>
<CTableHeaderCell className="bg-body-tertiary text-center">
<CIcon icon={cilPeople} />
</CTableHeaderCell>
<CTableHeaderCell className="bg-body-tertiary">User</CTableHeaderCell>
<CTableHeaderCell className="bg-body-tertiary text-center">
Country
</CTableHeaderCell>
<CTableHeaderCell className="bg-body-tertiary">Usage</CTableHeaderCell>
<CTableHeaderCell className="bg-body-tertiary text-center">
Payment Method
</CTableHeaderCell>
<CTableHeaderCell className="bg-body-tertiary">Activity</CTableHeaderCell>
</CTableRow>
</CTableHead>
<CTableBody>
{tableExample.map((item, index) => (
<CTableRow v-for="item in tableItems" key={index}>
<CTableDataCell className="text-center">
<CAvatar size="md" src={item.avatar.src} status={item.avatar.status} />
</CTableDataCell>
<CTableDataCell>
<div>{item.user.name}</div>
<div className="small text-body-secondary text-nowrap">
<span>{item.user.new ? 'New' : 'Recurring'}</span> | Registered:{' '}
{item.user.registered}
</div> </div>
</CTableDataCell>
<CTableDataCell className="text-center">
<CIcon size="xl" icon={item.country.flag} title={item.country.name} />
</CTableDataCell>
<CTableDataCell>
<div className="d-flex justify-content-between text-nowrap">
<div className="fw-semibold">{item.usage.value}%</div>
<div className="ms-3">
<small className="text-body-secondary">{item.usage.period}</small>
</div>
</div>
<CProgress thin color={item.usage.color} value={item.usage.value} />
</CTableDataCell>
<CTableDataCell className="text-center">
<CIcon size="xl" icon={item.payment.icon} />
</CTableDataCell>
<CTableDataCell>
<div className="small text-body-secondary text-nowrap">Last login</div>
<div className="fw-semibold text-nowrap">{item.activity}</div>
</CTableDataCell>
</CTableRow>
))}
</CTableBody>
</CTable>
</CCardBody>
</CCard>
</>
) )
} }