Skip to content

Commit d75d9bd

Browse files
Copilotlyzno1
andauthored
refactor: replace isDark conditional logic with Tailwind dark: prefix across codebase (iflabx#225)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lyzno1 <92089059+lyzno1@users.noreply.github.com> Co-authored-by: lyzno1 <yuanyouhuilyz@gmail.com>
1 parent 26ec653 commit d75d9bd

11 files changed

Lines changed: 106 additions & 286 deletions

components/admin/return-to-chat-button.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
'use client';
22

3-
import { useTheme } from '@lib/hooks/use-theme';
43
import { cn } from '@lib/utils';
54
import { Edit } from 'lucide-react';
65

76
import { useTranslations } from 'next-intl';
87
import Link from 'next/link';
98

109
export function ReturnToChatButton() {
11-
const { isDark } = useTheme();
1210
const t = useTranslations('pages.admin.layout.actions.returnToChatButton');
1311

1412
return (
@@ -17,9 +15,8 @@ export function ReturnToChatButton() {
1715
className={cn(
1816
'flex items-center gap-2 rounded-lg px-3 py-1.5 transition-all duration-200',
1917
'border',
20-
isDark
21-
? 'border-stone-600/50 bg-stone-700/50 text-stone-300 hover:border-stone-500 hover:bg-stone-600 hover:text-stone-100'
22-
: 'border-stone-200 bg-stone-100/80 text-stone-600 hover:border-stone-300 hover:bg-stone-200 hover:text-stone-900'
18+
'border-stone-200 bg-stone-100/80 text-stone-600 hover:border-stone-300 hover:bg-stone-200 hover:text-stone-900',
19+
'dark:border-stone-600/50 dark:bg-stone-700/50 dark:text-stone-300 dark:hover:border-stone-500 dark:hover:bg-stone-600 dark:hover:text-stone-100'
2320
)}
2421
>
2522
<Edit className="h-4 w-4" />

components/admin/users/user-table.tsx

Lines changed: 55 additions & 118 deletions
Large diffs are not rendered by default.

components/chat/page-loading-spinner.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,9 @@ interface SpinnerIconProps {
5656
* @description SVG spinner icon for loading indication
5757
*/
5858
function SpinnerIcon({ size = 24 }: SpinnerIconProps) {
59-
const { isDark } = useThemeColors();
60-
6159
return (
6260
<svg
63-
className={cn(
64-
'animate-spin',
65-
isDark ? 'text-stone-300' : 'text-stone-600'
66-
)}
61+
className={cn('animate-spin', 'text-stone-600 dark:text-stone-300')}
6762
width={size}
6863
height={size}
6964
xmlns="http://www.w3.org/2000/svg"

components/chat/scroll-to-bottom-button.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { usePathname } from 'next/navigation';
1616
*/
1717
export const ScrollToBottomButton = () => {
1818
const { isAtBottom } = useChatScrollStore();
19-
const { colors, isDark } = useThemeColors();
19+
const { colors } = useThemeColors();
2020
const resetScrollState = useChatScrollStore(state => state.resetScrollState);
2121
const pathname = usePathname();
2222
const t = useTranslations('pages.chat.input');

components/file-preview/file-preview-canvas.tsx

Lines changed: 26 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
'use client';
22

3-
import { useTheme } from '@lib/hooks';
43
import type { MessageAttachment } from '@lib/stores/chat-store';
54
import { useFilePreviewStore } from '@lib/stores/ui/file-preview-store';
65
import { cn, formatBytes } from '@lib/utils';
@@ -28,50 +27,20 @@ import { VideoPreview } from './previews/video-preview';
2827
/**
2928
* Loading skeleton component
3029
*/
31-
const LoadingSkeleton: React.FC<{ isDark: boolean }> = ({ isDark }) => {
30+
const LoadingSkeleton: React.FC = () => {
3231
const t = useTranslations('filePreview');
3332
return (
3433
<div className="animate-pulse space-y-4">
3534
<div className="flex items-center space-x-2">
36-
<RefreshCwIcon
37-
className={cn(
38-
'h-4 w-4 animate-spin',
39-
isDark ? 'text-stone-400' : 'text-stone-600'
40-
)}
41-
/>
42-
<span
43-
className={cn(
44-
'text-sm',
45-
isDark ? 'text-stone-400' : 'text-stone-600'
46-
)}
47-
>
35+
<RefreshCwIcon className="h-4 w-4 animate-spin text-stone-600 dark:text-stone-400" />
36+
<span className="text-sm text-stone-600 dark:text-stone-400">
4837
{t('loading')}
4938
</span>
5039
</div>
51-
<div
52-
className={cn(
53-
'space-y-3 rounded-md p-4',
54-
isDark ? 'bg-stone-800' : 'bg-stone-100'
55-
)}
56-
>
57-
<div
58-
className={cn(
59-
'h-4 rounded',
60-
isDark ? 'bg-stone-700' : 'bg-stone-200'
61-
)}
62-
/>
63-
<div
64-
className={cn(
65-
'h-4 w-3/4 rounded',
66-
isDark ? 'bg-stone-700' : 'bg-stone-200'
67-
)}
68-
/>
69-
<div
70-
className={cn(
71-
'h-4 w-1/2 rounded',
72-
isDark ? 'bg-stone-700' : 'bg-stone-200'
73-
)}
74-
/>
40+
<div className="space-y-3 rounded-md bg-stone-100 p-4 dark:bg-stone-800">
41+
<div className="h-4 rounded bg-stone-200 dark:bg-stone-700" />
42+
<div className="h-4 w-3/4 rounded bg-stone-200 dark:bg-stone-700" />
43+
<div className="h-4 w-1/2 rounded bg-stone-200 dark:bg-stone-700" />
7544
</div>
7645
</div>
7746
);
@@ -84,18 +53,10 @@ const ErrorDisplay: React.FC<{
8453
error: string;
8554
onRetry: () => void;
8655
onClearError: () => void;
87-
isDark: boolean;
88-
}> = ({ error, onRetry, onClearError, isDark }) => {
56+
}> = ({ error, onRetry, onClearError }) => {
8957
const t = useTranslations('filePreview');
9058
return (
91-
<div
92-
className={cn(
93-
'space-y-4 rounded-md border p-4',
94-
isDark
95-
? 'border-red-800 bg-red-900/20 text-red-200'
96-
: 'border-red-300 bg-red-50 text-red-800'
97-
)}
98-
>
59+
<div className="space-y-4 rounded-md border border-red-300 bg-red-50 p-4 text-red-800 dark:border-red-800 dark:bg-red-900/20 dark:text-red-200">
9960
<div className="flex items-start space-x-2">
10061
<AlertCircleIcon className="mt-0.5 h-5 w-5 flex-shrink-0" />
10162
<div className="flex-1">
@@ -106,24 +67,14 @@ const ErrorDisplay: React.FC<{
10667
<div className="flex space-x-2">
10768
<button
10869
onClick={onRetry}
109-
className={cn(
110-
'inline-flex items-center space-x-1 rounded px-3 py-1.5 text-sm font-medium transition-colors',
111-
isDark
112-
? 'bg-red-800 text-red-100 hover:bg-red-700'
113-
: 'bg-red-600 text-white hover:bg-red-700'
114-
)}
70+
className="inline-flex items-center space-x-1 rounded bg-red-600 px-3 py-1.5 text-sm font-medium text-white transition-colors hover:bg-red-700 dark:bg-red-800 dark:text-red-100 dark:hover:bg-red-700"
11571
>
11672
<RefreshCwIcon className="h-3 w-3" />
11773
<span>{t('retryButton')}</span>
11874
</button>
11975
<button
12076
onClick={onClearError}
121-
className={cn(
122-
'inline-flex items-center rounded px-3 py-1.5 text-sm font-medium transition-colors',
123-
isDark
124-
? 'text-red-200 hover:bg-red-800/50'
125-
: 'text-red-700 hover:bg-red-100'
126-
)}
77+
className="inline-flex items-center rounded px-3 py-1.5 text-sm font-medium text-red-700 transition-colors hover:bg-red-100 dark:text-red-200 dark:hover:bg-red-800/50"
12778
>
12879
{t('dismissButton')}
12980
</button>
@@ -138,20 +89,12 @@ const ErrorDisplay: React.FC<{
13889
const FileInfoFallback: React.FC<{
13990
file: MessageAttachment;
14091
onDownload: () => void;
141-
isDark: boolean;
142-
}> = ({ file, onDownload, isDark }) => {
92+
}> = ({ file, onDownload }) => {
14393
const t = useTranslations('filePreview');
14494
return (
14595
<div className="space-y-4">
14696
<h3 className="text-lg font-semibold">{t('fileInfo.title')}</h3>
147-
<div
148-
className={cn(
149-
'space-y-3 rounded-md border p-4',
150-
isDark
151-
? 'border-stone-700 bg-stone-800'
152-
: 'border-stone-200 bg-stone-50'
153-
)}
154-
>
97+
<div className="space-y-3 rounded-md border border-stone-200 bg-stone-50 p-4 dark:border-stone-700 dark:bg-stone-800">
15598
<div className="space-y-1 text-sm">
15699
<p>
157100
<strong>{t('fileInfo.name')}</strong> {file.name}
@@ -167,20 +110,13 @@ const FileInfoFallback: React.FC<{
167110
<div className="flex space-x-2">
168111
<button
169112
onClick={onDownload}
170-
className={cn(
171-
'inline-flex items-center space-x-2 rounded-md px-4 py-2 text-sm font-medium transition-colors',
172-
isDark
173-
? 'bg-stone-700 text-stone-200 hover:bg-stone-600'
174-
: 'bg-stone-200 text-stone-800 hover:bg-stone-300'
175-
)}
113+
className="inline-flex items-center space-x-2 rounded-md bg-stone-200 px-4 py-2 text-sm font-medium text-stone-800 transition-colors hover:bg-stone-300 dark:bg-stone-700 dark:text-stone-200 dark:hover:bg-stone-600"
176114
>
177115
<DownloadIcon className="h-4 w-4" />
178116
<span>{t('downloadButton')}</span>
179117
</button>
180118
</div>
181-
<p
182-
className={cn('text-xs', isDark ? 'text-stone-400' : 'text-stone-500')}
183-
>
119+
<p className="text-xs text-stone-500 dark:text-stone-400">
184120
{t('previewNotSupported')}
185121
</p>
186122
</div>
@@ -192,8 +128,7 @@ const FileInfoFallback: React.FC<{
192128
*/
193129
const FileContentViewer: React.FC<{
194130
file: MessageAttachment | null;
195-
isDark: boolean;
196-
}> = ({ file, isDark }) => {
131+
}> = ({ file }) => {
197132
const {
198133
previewContent,
199134
contentHeaders,
@@ -208,12 +143,7 @@ const FileContentViewer: React.FC<{
208143

209144
if (!file) {
210145
return (
211-
<div
212-
className={cn(
213-
'py-8 text-center',
214-
isDark ? 'text-stone-400' : 'text-stone-600'
215-
)}
216-
>
146+
<div className="py-8 text-center text-stone-600 dark:text-stone-400">
217147
{t('noFileSelected')}
218148
</div>
219149
);
@@ -228,7 +158,7 @@ const FileContentViewer: React.FC<{
228158

229159
// Show loading state
230160
if (isLoading) {
231-
return <LoadingSkeleton isDark={isDark} />;
161+
return <LoadingSkeleton />;
232162
}
233163

234164
// Show error state
@@ -238,16 +168,13 @@ const FileContentViewer: React.FC<{
238168
error={error}
239169
onRetry={handleRetry}
240170
onClearError={clearError}
241-
isDark={isDark}
242171
/>
243172
);
244173
}
245174

246175
// Show fallback if no content available
247176
if (!previewContent || !contentHeaders) {
248-
return (
249-
<FileInfoFallback file={file} onDownload={downloadFile} isDark={isDark} />
250-
);
177+
return <FileInfoFallback file={file} onDownload={downloadFile} />;
251178
}
252179

253180
// Route to appropriate preview component based on content type
@@ -324,15 +251,12 @@ const FileContentViewer: React.FC<{
324251
}
325252

326253
// Fallback for unsupported types
327-
return (
328-
<FileInfoFallback file={file} onDownload={downloadFile} isDark={isDark} />
329-
);
254+
return <FileInfoFallback file={file} onDownload={downloadFile} />;
330255
};
331256

332257
export const FilePreviewCanvas = () => {
333258
const { isPreviewOpen, currentPreviewFile, closePreview } =
334259
useFilePreviewStore();
335-
const { isDark } = useTheme();
336260
const pathname = usePathname();
337261
const t = useTranslations('filePreview');
338262

@@ -367,9 +291,8 @@ export const FilePreviewCanvas = () => {
367291
'fixed top-0 right-0 z-50 h-full',
368292
'flex flex-col',
369293
'w-[85%] md:w-[60%] lg:w-[50%] xl:w-[40%]',
370-
isDark
371-
? 'border-l border-stone-700 bg-stone-800 text-stone-100'
372-
: 'border-l border-stone-200 bg-white text-stone-900'
294+
'border-l border-stone-200 bg-white text-stone-900',
295+
'dark:border-l dark:border-stone-700 dark:bg-stone-800 dark:text-stone-100'
373296
)}
374297
variants={panelVariants}
375298
initial="hidden"
@@ -380,7 +303,7 @@ export const FilePreviewCanvas = () => {
380303
<div
381304
className={cn(
382305
'flex flex-shrink-0 items-center justify-between border-b p-4',
383-
isDark ? 'border-stone-700' : 'border-stone-200'
306+
'border-stone-200 dark:border-stone-700'
384307
)}
385308
>
386309
<h2
@@ -393,20 +316,16 @@ export const FilePreviewCanvas = () => {
393316
onClick={closePreview}
394317
className={cn(
395318
'rounded-full p-1',
396-
isDark
397-
? 'text-stone-300 hover:bg-stone-700 hover:text-stone-200'
398-
: 'text-stone-600 hover:bg-stone-200 hover:text-stone-800'
319+
'text-stone-600 hover:bg-stone-200 hover:text-stone-800',
320+
'dark:text-stone-300 dark:hover:bg-stone-700 dark:hover:text-stone-200'
399321
)}
400322
aria-label={t('closeButton')}
401323
>
402324
<XIcon className="h-5 w-5" />
403325
</button>
404326
</div>
405327
<div className="flex flex-1 flex-col overflow-y-auto p-6">
406-
<FileContentViewer
407-
file={currentPreviewFile}
408-
isDark={isDark ?? false}
409-
/>
328+
<FileContentViewer file={currentPreviewFile} />
410329
</div>
411330
</motion.div>
412331
)}

components/nav-bar/nav-button.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
'use client';
22

3-
import { useTheme } from '@lib/hooks/use-theme';
43
import { cn } from '@lib/utils';
54

65
import React from 'react';
@@ -18,8 +17,6 @@ export function NavButton({
1817
className,
1918
...props
2019
}: NavButtonProps) {
21-
const { isDark } = useTheme();
22-
2320
return (
2421
<button
2522
className={cn(
@@ -30,9 +27,8 @@ export function NavButton({
3027
// Responsive adjustment (if needed)
3128
// "sm:px-4 sm:py-2",
3229
// Theme-aware hover effect
33-
isDark
34-
? 'text-gray-300 hover:bg-gray-700/50 hover:text-gray-100'
35-
: 'text-gray-600 hover:bg-gray-100 hover:text-gray-900',
30+
'text-gray-600 hover:bg-gray-100 hover:text-gray-900',
31+
'dark:text-gray-300 dark:hover:bg-gray-700/50 dark:hover:text-gray-100',
3632
// Disabled state
3733
'disabled:pointer-events-none disabled:opacity-50',
3834
// External class name passed in

components/sidebar/chat-skeleton.tsx

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,22 @@ import { cn } from '@lib/utils';
88
import * as React from 'react';
99

1010
interface ChatSkeletonProps {
11-
isDark: boolean;
1211
count?: number;
1312
}
1413

15-
export function ChatSkeleton({ isDark, count = 5 }: ChatSkeletonProps) {
14+
export function ChatSkeleton({ count = 5 }: ChatSkeletonProps) {
1615
return (
1716
<div className="mb-2 space-y-1">
1817
{Array(count)
1918
.fill(0)
2019
.map((_, index) => (
21-
<ChatSkeletonItem key={`skeleton-${index}`} isDark={isDark} />
20+
<ChatSkeletonItem key={`skeleton-${index}`} />
2221
))}
2322
</div>
2423
);
2524
}
2625

27-
interface ChatSkeletonItemProps {
28-
isDark: boolean;
29-
}
30-
31-
export function ChatSkeletonItem({ isDark }: ChatSkeletonItemProps) {
26+
export function ChatSkeletonItem() {
3227
// Skeleton screen project, simulating the appearance of the chat project
3328
// Do not use outer frame background color, only display the animation effect of internal elements
3429
return (
@@ -37,13 +32,13 @@ export function ChatSkeletonItem({ isDark }: ChatSkeletonItemProps) {
3732
<div
3833
className={cn(
3934
'mr-3 h-5 w-5 flex-shrink-0 animate-pulse rounded-full',
40-
isDark ? 'bg-stone-600' : 'bg-stone-400'
35+
'bg-stone-400 dark:bg-stone-600'
4136
)}
4237
/>
4338
<div
4439
className={cn(
4540
'h-4 w-[70%] animate-pulse rounded-md',
46-
isDark ? 'bg-stone-600' : 'bg-stone-400'
41+
'bg-stone-400 dark:bg-stone-600'
4742
)}
4843
/>
4944
</div>

0 commit comments

Comments
 (0)