라이트 모드 버튼 스타일 수정
This commit is contained in:
+9
-1
@@ -1,9 +1,17 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="ko">
|
<html lang="ko" class="theme-dark">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>BizCare</title>
|
<title>BizCare</title>
|
||||||
|
<script>
|
||||||
|
try {
|
||||||
|
var t = localStorage.getItem('bizcare_ui_theme')
|
||||||
|
if (t === 'light' || t === 'dark' || t === 'blue') {
|
||||||
|
document.documentElement.className = 'theme-' + t
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|||||||
@@ -18,7 +18,9 @@ client.interceptors.response.use(
|
|||||||
(res) => res,
|
(res) => res,
|
||||||
(err) => {
|
(err) => {
|
||||||
if (err.response?.status === 401) {
|
if (err.response?.status === 401) {
|
||||||
|
const theme = localStorage.getItem('bizcare_ui_theme')
|
||||||
localStorage.clear()
|
localStorage.clear()
|
||||||
|
if (theme) localStorage.setItem('bizcare_ui_theme', theme)
|
||||||
if (!window.location.pathname.includes('/login')) window.location.href = '/login'
|
if (!window.location.pathname.includes('/login')) window.location.href = '/login'
|
||||||
}
|
}
|
||||||
const msg = err.response?.data?.msg
|
const msg = err.response?.data?.msg
|
||||||
|
|||||||
@@ -129,7 +129,9 @@ export default function AgentShell({ shop = false }: Props) {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const logout = () => {
|
const logout = () => {
|
||||||
|
const theme = localStorage.getItem('bizcare_ui_theme')
|
||||||
localStorage.clear()
|
localStorage.clear()
|
||||||
|
if (theme) localStorage.setItem('bizcare_ui_theme', theme)
|
||||||
navigate('/login')
|
navigate('/login')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,14 @@ import { StrictMode } from 'react'
|
|||||||
import { createRoot } from 'react-dom/client'
|
import { createRoot } from 'react-dom/client'
|
||||||
import { BrowserRouter } from 'react-router-dom'
|
import { BrowserRouter } from 'react-router-dom'
|
||||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||||
import { applyTheme, loadTheme } from './theme'
|
import { applyTheme, loadTheme, saveTheme } from './theme'
|
||||||
import { ThemeProvider } from './themeContext'
|
import { ThemeProvider } from './themeContext'
|
||||||
import './index.css'
|
import './index.css'
|
||||||
import App from './App.tsx'
|
import App from './App.tsx'
|
||||||
|
|
||||||
applyTheme(loadTheme())
|
const initialTheme = loadTheme()
|
||||||
|
applyTheme(initialTheme)
|
||||||
|
saveTheme(initialTheme)
|
||||||
|
|
||||||
const queryClient = new QueryClient({
|
const queryClient = new QueryClient({
|
||||||
defaultOptions: {
|
defaultOptions: {
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ export default function ProductHomePage() {
|
|||||||
<p>홈렌탈상품을 등록 및 관리하실 수 있습니다.</p>
|
<p>홈렌탈상품을 등록 및 관리하실 수 있습니다.</p>
|
||||||
</div>
|
</div>
|
||||||
<Space>
|
<Space>
|
||||||
<Button icon={<SyncOutlined />} loading={sync.isPending} onClick={() => sync.mutate()}>
|
<Button type="primary" icon={<SyncOutlined />} loading={sync.isPending} onClick={() => sync.mutate()}>
|
||||||
기본상품 동기화
|
기본상품 동기화
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="primary" icon={<PlusSquareOutlined />} onClick={openCreate}>
|
<Button type="primary" icon={<PlusSquareOutlined />} onClick={openCreate}>
|
||||||
|
|||||||
@@ -227,6 +227,7 @@ export default function ProductInternetPage() {
|
|||||||
</div>
|
</div>
|
||||||
<Space>
|
<Space>
|
||||||
<Button
|
<Button
|
||||||
|
type="primary"
|
||||||
icon={<SyncOutlined />}
|
icon={<SyncOutlined />}
|
||||||
loading={sync.isPending}
|
loading={sync.isPending}
|
||||||
onClick={() => sync.mutate()}
|
onClick={() => sync.mutate()}
|
||||||
|
|||||||
@@ -4994,3 +4994,58 @@ html.theme-light .ant-table-bordered .ant-table-thead > tr > th,
|
|||||||
html.theme-light .ant-table-bordered .ant-table-tbody > tr > td {
|
html.theme-light .ant-table-bordered .ant-table-tbody > tr > td {
|
||||||
border-color: #d9dee5 !important;
|
border-color: #d9dee5 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 라이트 모드: 액션 버튼 = 파란 배경 + 흰 텍스트로 통일 (primary와 동일) */
|
||||||
|
html.theme-light .ant-btn.ant-btn-default:not(.ant-btn-dangerous):not(.ant-btn-disabled):not(:disabled),
|
||||||
|
html.theme-light .ant-btn.ant-btn-dashed:not(.ant-btn-dangerous):not(.ant-btn-disabled):not(:disabled) {
|
||||||
|
background: var(--primary) !important;
|
||||||
|
border-color: var(--primary) !important;
|
||||||
|
color: #fff !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
text-shadow: none !important;
|
||||||
|
}
|
||||||
|
html.theme-light .ant-btn.ant-btn-default:not(.ant-btn-dangerous):not(.ant-btn-disabled):not(:disabled):hover,
|
||||||
|
html.theme-light .ant-btn.ant-btn-default:not(.ant-btn-dangerous):not(.ant-btn-disabled):not(:disabled):focus,
|
||||||
|
html.theme-light .ant-btn.ant-btn-default:not(.ant-btn-dangerous):not(.ant-btn-disabled):not(:disabled):active,
|
||||||
|
html.theme-light .ant-btn.ant-btn-dashed:not(.ant-btn-dangerous):not(.ant-btn-disabled):not(:disabled):hover,
|
||||||
|
html.theme-light .ant-btn.ant-btn-dashed:not(.ant-btn-dangerous):not(.ant-btn-disabled):not(:disabled):focus,
|
||||||
|
html.theme-light .ant-btn.ant-btn-dashed:not(.ant-btn-dangerous):not(.ant-btn-disabled):not(:disabled):active {
|
||||||
|
background: var(--primary-dark) !important;
|
||||||
|
border-color: var(--primary-dark) !important;
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
html.theme-light .ant-btn.ant-btn-default:not(.ant-btn-dangerous) .anticon,
|
||||||
|
html.theme-light .ant-btn.ant-btn-dashed:not(.ant-btn-dangerous) .anticon {
|
||||||
|
color: inherit !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 페이지별 회색/면 버튼도 라이트에서는 동일 스타일 */
|
||||||
|
html.theme-light .sms-send-footer .ant-btn-default,
|
||||||
|
html.theme-light .sms-contact-footer-right .ant-btn-default,
|
||||||
|
html.theme-light .abook-create-footer .ant-btn-default,
|
||||||
|
html.theme-light .homes-pref-page .pref-table td .ant-btn-default,
|
||||||
|
html.theme-light .homes-pref-page .pref-table td .ant-btn-default:hover,
|
||||||
|
html.theme-light .turnover-mode .ant-btn-default,
|
||||||
|
html.theme-light .recovery-actions .ant-btn,
|
||||||
|
html.theme-light .sheet-presets .ant-btn,
|
||||||
|
html.theme-light .sheet-clear,
|
||||||
|
html.theme-light .farebox-gray-btn:not(:disabled),
|
||||||
|
html.theme-light .calc-fullscreen-drawer-root .ant-btn-default,
|
||||||
|
html.theme-light .calc-prepared-drawer-root .ant-btn-default {
|
||||||
|
background: var(--primary) !important;
|
||||||
|
border-color: var(--primary) !important;
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
html.theme-light .sms-send-footer .ant-btn-default:hover,
|
||||||
|
html.theme-light .sms-contact-footer-right .ant-btn-default:hover,
|
||||||
|
html.theme-light .abook-create-footer .ant-btn-default:hover,
|
||||||
|
html.theme-light .turnover-mode .ant-btn-default:hover,
|
||||||
|
html.theme-light .recovery-actions .ant-btn:hover,
|
||||||
|
html.theme-light .sheet-presets .ant-btn:hover,
|
||||||
|
html.theme-light .sheet-clear:hover,
|
||||||
|
html.theme-light .farebox-gray-btn:not(:disabled):hover {
|
||||||
|
background: var(--primary-dark) !important;
|
||||||
|
border-color: var(--primary-dark) !important;
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
+22
-3
@@ -6,17 +6,36 @@ export const THEMES: { value: Theme; label: string }[] = [
|
|||||||
{ value: 'blue', label: '블루' },
|
{ value: 'blue', label: '블루' },
|
||||||
]
|
]
|
||||||
|
|
||||||
const STORAGE_KEY = 'bizcare_theme'
|
/** 기본 테마 — 최초 실행 / 저장값 없음 */
|
||||||
|
export const DEFAULT_THEME: Theme = 'dark'
|
||||||
|
|
||||||
|
/** v2: 이전 기본값(light)이 localStorage에 남아 다크 기본이 무시되던 문제 해소 */
|
||||||
|
const STORAGE_KEY = 'bizcare_ui_theme'
|
||||||
|
const LEGACY_KEYS = ['bizcare_theme', 'billcare_theme']
|
||||||
const VALID: Theme[] = ['light', 'dark', 'blue']
|
const VALID: Theme[] = ['light', 'dark', 'blue']
|
||||||
|
|
||||||
|
function isTheme(value: string | null): value is Theme {
|
||||||
|
return !!value && (VALID as string[]).includes(value)
|
||||||
|
}
|
||||||
|
|
||||||
export function loadTheme(): Theme {
|
export function loadTheme(): Theme {
|
||||||
try {
|
try {
|
||||||
const raw = localStorage.getItem(STORAGE_KEY)
|
const raw = localStorage.getItem(STORAGE_KEY)
|
||||||
if (raw && (VALID as string[]).includes(raw)) return raw as Theme
|
if (isTheme(raw)) return raw
|
||||||
|
|
||||||
|
// 예전 키: 사용자가 다크/블루를 고른 경우만 이관. light(구 기본값)는 무시 → 다크
|
||||||
|
for (const key of LEGACY_KEYS) {
|
||||||
|
const legacy = localStorage.getItem(key)
|
||||||
|
if (!isTheme(legacy)) continue
|
||||||
|
localStorage.removeItem(key)
|
||||||
|
if (legacy === 'light') continue
|
||||||
|
localStorage.setItem(STORAGE_KEY, legacy)
|
||||||
|
return legacy
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
/* private mode */
|
/* private mode */
|
||||||
}
|
}
|
||||||
return 'dark'
|
return DEFAULT_THEME
|
||||||
}
|
}
|
||||||
|
|
||||||
export function applyTheme(theme: Theme): void {
|
export function applyTheme(theme: Theme): void {
|
||||||
|
|||||||
Reference in New Issue
Block a user