UI: Implement unified dark theme across all components
This commit is contained in:
parent
1185630616
commit
2ad11142ad
@ -29,13 +29,13 @@ function Navigation() {
|
||||
];
|
||||
|
||||
return (
|
||||
<nav className="bg-gray-900 border-b border-gray-800">
|
||||
<nav className="bg-dark-card border-b border-dark-border shadow-lg">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex items-center justify-between h-16">
|
||||
<div className="flex items-center gap-8">
|
||||
<Link to="/" className="flex items-center gap-2">
|
||||
<Link to="/" className="flex items-center gap-2 hover:opacity-90 transition-opacity">
|
||||
<span className="text-2xl">🤖</span>
|
||||
<span className="text-xl font-bold text-white">AI Review Agent</span>
|
||||
<span className="text-xl font-bold text-dark-text-primary">AI Review Agent</span>
|
||||
</Link>
|
||||
|
||||
<div className="flex gap-2">
|
||||
@ -43,14 +43,14 @@ function Navigation() {
|
||||
<Link
|
||||
key={link.path}
|
||||
to={link.path}
|
||||
className={`flex items-center gap-2 px-4 py-2 rounded-lg transition-colors ${
|
||||
className={`flex items-center gap-2 px-4 py-2 rounded-lg transition-all duration-200 ${
|
||||
location.pathname === link.path
|
||||
? 'bg-gray-800 text-white'
|
||||
: 'text-gray-400 hover:text-white hover:bg-gray-800'
|
||||
? 'bg-dark-hover text-dark-text-primary shadow-sm'
|
||||
: 'text-dark-text-secondary hover:text-dark-text-primary hover:bg-dark-hover/50'
|
||||
}`}
|
||||
>
|
||||
<span>{link.icon}</span>
|
||||
<span>{link.label}</span>
|
||||
<span className="font-medium">{link.label}</span>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
@ -65,7 +65,7 @@ function Navigation() {
|
||||
|
||||
function AppContent() {
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-900">
|
||||
<div className="min-h-screen bg-dark-bg">
|
||||
<Navigation />
|
||||
|
||||
<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||||
|
||||
@ -31,13 +31,13 @@ export const Modal: React.FC<ModalProps> = ({
|
||||
const getIconAndColor = () => {
|
||||
switch (type) {
|
||||
case 'success':
|
||||
return { icon: '✅', color: 'text-green-600', bgColor: 'bg-green-50' };
|
||||
return { icon: '✅', color: 'text-green-400', bgColor: 'bg-green-900/30 border-green-700' };
|
||||
case 'error':
|
||||
return { icon: '❌', color: 'text-red-600', bgColor: 'bg-red-50' };
|
||||
return { icon: '❌', color: 'text-red-400', bgColor: 'bg-red-900/30 border-red-700' };
|
||||
case 'warning':
|
||||
return { icon: '⚠️', color: 'text-yellow-600', bgColor: 'bg-yellow-50' };
|
||||
return { icon: '⚠️', color: 'text-yellow-400', bgColor: 'bg-yellow-900/30 border-yellow-700' };
|
||||
default:
|
||||
return { icon: 'ℹ️', color: 'text-blue-600', bgColor: 'bg-blue-50' };
|
||||
return { icon: 'ℹ️', color: 'text-blue-400', bgColor: 'bg-blue-900/30 border-blue-700' };
|
||||
}
|
||||
};
|
||||
|
||||
@ -45,11 +45,11 @@ export const Modal: React.FC<ModalProps> = ({
|
||||
|
||||
return (
|
||||
<div
|
||||
className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50"
|
||||
className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-70"
|
||||
onClick={onClose}
|
||||
>
|
||||
<div
|
||||
className="bg-white rounded-lg shadow-xl max-w-md w-full mx-4 animate-scale-in"
|
||||
className="bg-dark-card rounded-lg shadow-2xl max-w-md w-full mx-4 animate-scale-in border border-dark-border"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<div className={`${bgColor} px-6 py-4 rounded-t-lg border-b`}>
|
||||
@ -58,13 +58,13 @@ export const Modal: React.FC<ModalProps> = ({
|
||||
{title}
|
||||
</h3>
|
||||
</div>
|
||||
<div className="px-6 py-4">
|
||||
<div className="px-6 py-4 text-dark-text-primary">
|
||||
{children}
|
||||
</div>
|
||||
<div className="px-6 py-4 bg-gray-50 rounded-b-lg flex justify-end">
|
||||
<div className="px-6 py-4 bg-dark-bg/50 rounded-b-lg flex justify-end border-t border-dark-border">
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="px-4 py-2 bg-gray-600 text-white rounded hover:bg-gray-700 transition-colors"
|
||||
className="px-4 py-2 bg-dark-hover text-dark-text-primary rounded-lg hover:bg-dark-hover/80 transition-colors font-medium"
|
||||
>
|
||||
Закрыть
|
||||
</button>
|
||||
@ -102,11 +102,11 @@ export const ConfirmModal: React.FC<ConfirmModalProps> = ({
|
||||
const getIconAndColor = () => {
|
||||
switch (type) {
|
||||
case 'error':
|
||||
return { icon: '❌', color: 'text-red-600', bgColor: 'bg-red-50', btnColor: 'bg-red-600 hover:bg-red-700' };
|
||||
return { icon: '❌', color: 'text-red-400', bgColor: 'bg-red-900/30 border-red-700', btnColor: 'bg-red-600 hover:bg-red-700' };
|
||||
case 'info':
|
||||
return { icon: 'ℹ️', color: 'text-blue-600', bgColor: 'bg-blue-50', btnColor: 'bg-blue-600 hover:bg-blue-700' };
|
||||
return { icon: 'ℹ️', color: 'text-blue-400', bgColor: 'bg-blue-900/30 border-blue-700', btnColor: 'bg-blue-600 hover:bg-blue-700' };
|
||||
default:
|
||||
return { icon: '⚠️', color: 'text-yellow-600', bgColor: 'bg-yellow-50', btnColor: 'bg-yellow-600 hover:bg-yellow-700' };
|
||||
return { icon: '⚠️', color: 'text-yellow-400', bgColor: 'bg-yellow-900/30 border-yellow-700', btnColor: 'bg-yellow-600 hover:bg-yellow-700' };
|
||||
}
|
||||
};
|
||||
|
||||
@ -114,11 +114,11 @@ export const ConfirmModal: React.FC<ConfirmModalProps> = ({
|
||||
|
||||
return (
|
||||
<div
|
||||
className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50"
|
||||
className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-70"
|
||||
onClick={isLoading ? undefined : onClose}
|
||||
>
|
||||
<div
|
||||
className="bg-white rounded-lg shadow-xl max-w-md w-full mx-4 animate-scale-in"
|
||||
className="bg-dark-card rounded-lg shadow-2xl max-w-md w-full mx-4 animate-scale-in border border-dark-border"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<div className={`${bgColor} px-6 py-4 rounded-t-lg border-b`}>
|
||||
@ -128,20 +128,20 @@ export const ConfirmModal: React.FC<ConfirmModalProps> = ({
|
||||
</h3>
|
||||
</div>
|
||||
<div className="px-6 py-4">
|
||||
<p className="text-gray-700">{message}</p>
|
||||
<p className="text-dark-text-primary">{message}</p>
|
||||
</div>
|
||||
<div className="px-6 py-4 bg-gray-50 rounded-b-lg flex justify-end gap-3">
|
||||
<div className="px-6 py-4 bg-dark-bg/50 rounded-b-lg flex justify-end gap-3 border-t border-dark-border">
|
||||
<button
|
||||
onClick={onClose}
|
||||
disabled={isLoading}
|
||||
className="px-4 py-2 bg-gray-300 text-gray-700 rounded hover:bg-gray-400 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
className="px-4 py-2 bg-dark-hover text-dark-text-secondary rounded-lg hover:bg-dark-hover/80 transition-colors disabled:opacity-50 disabled:cursor-not-allowed font-medium"
|
||||
>
|
||||
{cancelText}
|
||||
</button>
|
||||
<button
|
||||
onClick={onConfirm}
|
||||
disabled={isLoading}
|
||||
className={`px-4 py-2 text-white rounded transition-colors disabled:opacity-50 disabled:cursor-not-allowed ${btnColor}`}
|
||||
className={`px-4 py-2 text-white rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed font-medium ${btnColor}`}
|
||||
>
|
||||
{isLoading ? '⏳ Загрузка...' : confirmText}
|
||||
</button>
|
||||
|
||||
@ -22,9 +22,9 @@
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
color-scheme: dark;
|
||||
color: #F1F5F9;
|
||||
background-color: #0F172A;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
@ -36,9 +36,85 @@ body {
|
||||
margin: 0;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
background-color: #0F172A;
|
||||
color: #F1F5F9;
|
||||
}
|
||||
|
||||
#root {
|
||||
min-height: 100vh;
|
||||
background-color: #0F172A;
|
||||
}
|
||||
|
||||
/* Темная тема для всех элементов */
|
||||
* {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #475569 #1E293B;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-track {
|
||||
background: #1E293B;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb {
|
||||
background: #475569;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb:hover {
|
||||
background: #64748B;
|
||||
}
|
||||
|
||||
/* Убрать светлые элементы из браузера */
|
||||
input, textarea, select {
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
/* Темная тема для всех форм */
|
||||
input[type="text"],
|
||||
input[type="email"],
|
||||
input[type="password"],
|
||||
input[type="url"],
|
||||
input[type="number"],
|
||||
textarea,
|
||||
select {
|
||||
@apply bg-dark-card border-dark-border text-dark-text-primary;
|
||||
@apply focus:border-blue-500 focus:ring-2 focus:ring-blue-500/20;
|
||||
}
|
||||
|
||||
input[type="text"]:disabled,
|
||||
input[type="email"]:disabled,
|
||||
input[type="password"]:disabled,
|
||||
input[type="url"]:disabled,
|
||||
input[type="number"]:disabled,
|
||||
textarea:disabled,
|
||||
select:disabled {
|
||||
@apply bg-dark-bg/50 text-dark-text-muted cursor-not-allowed;
|
||||
}
|
||||
|
||||
input::placeholder,
|
||||
textarea::placeholder {
|
||||
@apply text-dark-text-muted;
|
||||
}
|
||||
|
||||
/* Темная тема для checkbox и radio */
|
||||
input[type="checkbox"],
|
||||
input[type="radio"] {
|
||||
@apply bg-dark-card border-dark-border;
|
||||
@apply checked:bg-blue-600 checked:border-blue-600;
|
||||
}
|
||||
|
||||
/* Темная тема для кнопок */
|
||||
button {
|
||||
@apply transition-colors duration-200;
|
||||
}
|
||||
|
||||
/* Темная тема для ссылок */
|
||||
a {
|
||||
@apply transition-colors duration-200;
|
||||
}
|
||||
|
||||
|
||||
@ -4,8 +4,23 @@ export default {
|
||||
"./index.html",
|
||||
"./src/**/*.{js,ts,jsx,tsx}",
|
||||
],
|
||||
darkMode: 'class',
|
||||
theme: {
|
||||
extend: {},
|
||||
extend: {
|
||||
colors: {
|
||||
dark: {
|
||||
bg: '#0F172A', // Основной фон
|
||||
card: '#1E293B', // Карточки
|
||||
border: '#334155', // Границы
|
||||
hover: '#475569', // Hover эффекты
|
||||
text: {
|
||||
primary: '#F1F5F9', // Основной текст
|
||||
secondary: '#94A3B8', // Вторичный текст
|
||||
muted: '#64748B', // Приглушенный текст
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user