Skip to content

Commit 6f6749d

Browse files
committed
refactor: enhance UI components and fix styling issues
1 parent b50cf67 commit 6f6749d

7 files changed

Lines changed: 67 additions & 101 deletions

File tree

src/renderer/component/button/button.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type React from 'react'
2+
import { IoReload } from 'react-icons/io5'
23

34
interface ButtonProps {
45
onClick?: () => void
@@ -37,8 +38,8 @@ export function Button(prop: ButtonProps) {
3738
{prop.loading
3839
? prop.loadingText || (
3940
<div className="flex items-center gap-1">
40-
{/* <Icon name="spinner" className="animate-spin" /> */}
41-
<span className="text-xs">wait...</span>
41+
<IoReload size={18} className="animate-spin" />
42+
{/* <span className="text-xs">wait...</span> */}
4243
</div>
4344
)
4445
: prop.children}

src/renderer/component/cards/advertisement.card.component.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export function AdvertisementCardComponent() {
4444
return (
4545
<div
4646
className={
47-
'p-2bg-base-200 rounded-2xl shadow-sm h-17.5 flex items-center justify-center'
47+
'p-2 bg-base-200 rounded-2xl h-17.5 flex items-center justify-center'
4848
}
4949
>
5050
<div className="flex flex-row items-center gap-2">

src/renderer/component/input/text-input.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ export const TextInput = memo(function TextInput({
105105
onKeyDown,
106106
dir: direction,
107107
placeholder: placeholder || '',
108-
className: `input bg-content w-full text-[14px] ${sizes[size]} rounded-xl !outline-none transition-all duration-300 focus:ring-1 focus:ring-blue-500/20 focus:border-primary font-light ${className}`,
108+
className: `input w-full text-[14px] ${sizes[size]} rounded-xl !outline-none transition-all duration-300 focus:ring-1 focus:ring-blue-500/20 focus:border-primary font-light ${className}`,
109109
onChange: handleChange,
110110
maxLength,
111111
autoComplete,

src/renderer/component/modals/add-dns.component.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ function InputDNS(index: number, className: string, onChange: any) {
349349
<input
350350
key={index}
351351
type="text"
352-
className={`${className} w-10 h-10 border-none rounded font-[Inter] outline outline-1 outline-gray-700/20 dark:outline-none dark:text-gray-300/95 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-indigo-500 text-center`}
352+
className={`${className} input w-10 p-0! h-10 rounded-xl font-[Inter] outline-none! transition-all duration-300 focus:ring-1 focus:ring-primary/20 focus:border-primary text-center`}
353353
maxLength={3}
354354
onChange={onChange}
355355
/>

src/renderer/component/modals/confirmation-modal.tsx

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ export function ConfirmationModal({
4747
isOpen,
4848
onClose,
4949
onConfirm,
50-
title = 'تأیید عملیات',
51-
message = 'آیا از انجام این عملیات اطمینان دارید؟',
52-
confirmText = 'تأیید',
53-
cancelText = 'انصراف',
50+
title = 'Confirm Operation',
51+
message = 'Are you sure you want to perform this operation?',
52+
confirmText = 'Confirm',
53+
cancelText = 'Cancel',
5454
variant = 'danger',
5555
isLoading = false,
5656
icon,
57-
direction = 'rtl',
57+
direction,
5858
}: ConfirmationModalProps) {
5959
const config = variantConfig[variant]
6060
const displayIcon = icon || config.icon
@@ -97,29 +97,28 @@ export function ConfirmationModal({
9797
</div>
9898

9999
<div className="flex gap-3 pt-2">
100+
<Button
101+
onClick={handleCancel}
102+
size="md"
103+
disabled={isLoading}
104+
className="flex-1 border border-content/20 text-content hover:bg-base-300/50 rounded-2xl"
105+
>
106+
{cancelText}
107+
</Button>
100108
<Button
101109
onClick={handleConfirm}
102110
size="md"
103111
disabled={isLoading}
104112
loading={isLoading}
105113
loadingText={
106114
<div className="flex items-center gap-1">
107-
{/* <IconLoading className="!mx-0 !text-white" /> */}
108-
<span className="text-xs">در حال انجام...</span>
115+
<span className="text-xs">Please wait ...</span>
109116
</div>
110117
}
111118
className={`flex-1 ${config.confirmBg} ${config.confirmText} border-none rounded-2xl`}
112119
>
113120
{confirmText}
114121
</Button>
115-
<Button
116-
onClick={handleCancel}
117-
size="md"
118-
disabled={isLoading}
119-
className="flex-1 border border-content/20 text-content hover:bg-base-300/50 rounded-2xl"
120-
>
121-
{cancelText}
122-
</Button>
123122
</div>
124123
</div>
125124
</Modal>

src/renderer/component/modals/modal.tsx

Lines changed: 46 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -15,31 +15,11 @@ type ModalProps = {
1515
}
1616

1717
const sizeClasses = {
18-
sm: {
19-
w: 'w-[calc(100vw-2rem)] max-w-sm',
20-
h: 'max-h-[calc(100vh-4rem)] md:max-h-[560px]',
21-
minH: 'min-h-[180px]',
22-
},
23-
md: {
24-
w: 'w-[calc(100vw-2rem)] max-w-md',
25-
h: 'max-h-[calc(100vh-4rem)] md:max-h-[640px]',
26-
minH: 'min-h-[200px]',
27-
},
28-
lg: {
29-
w: 'w-[calc(100vw-2rem)] max-w-lg',
30-
h: 'max-h-[calc(100vh-4rem)] md:max-h-[720px]',
31-
minH: 'min-h-[240px]',
32-
},
33-
xl: {
34-
w: 'w-[calc(100vw-2rem)] max-w-4xl',
35-
h: 'max-h-[calc(100vh-4rem)] md:max-h-[800px]',
36-
minH: 'min-h-[280px]',
37-
},
38-
full: {
39-
w: 'w-[calc(100vw-1rem)] max-w-5xl',
40-
h: 'h-[calc(100vh-4rem)] md:h-[calc(100vh-6rem)]',
41-
minH: 'min-h-[calc(100vh-4rem)]',
42-
},
18+
sm: 'max-w-sm max-h-[80vh]',
19+
md: 'max-w-md max-h-[80vh]',
20+
lg: 'max-w-lg max-h-[80vh]',
21+
xl: 'max-w-4xl max-h-[80vh]',
22+
full: 'max-w-[95vw] max-h-[95vh]',
4323
} as const
4424

4525
export default function Modal({
@@ -53,95 +33,81 @@ export default function Modal({
5333
showCloseButton = true,
5434
className = '',
5535
}: ModalProps) {
56-
const modalRef = useRef<HTMLDivElement>(null)
57-
const sizeValue = sizeClasses[size] || sizeClasses.md
36+
const dialogRef = useRef<HTMLDialogElement>(null)
5837

59-
// Lock body scroll when modal is open
6038
useEffect(() => {
6139
if (isOpen) {
62-
document.documentElement.classList.add('modal-isActive')
63-
document.body.style.overflow = 'hidden'
40+
dialogRef.current?.showModal()
6441
} else {
65-
document.documentElement.classList.remove('modal-isActive')
66-
document.body.style.overflow = ''
67-
}
68-
return () => {
69-
document.documentElement.classList.remove('modal-isActive')
70-
document.body.style.overflow = ''
42+
dialogRef.current?.close()
7143
}
7244
}, [isOpen])
7345

74-
// Handle keyboard events
75-
useEffect(() => {
76-
if (!isOpen) return
77-
78-
const handleKeyDown = (e: KeyboardEvent) => {
79-
if (e.key === 'Escape') {
80-
e.preventDefault()
81-
onClose()
82-
}
46+
const handleBackdropClick = (e: React.MouseEvent<HTMLDialogElement>) => {
47+
if (!closeOnBackdropClick) return
48+
const rect = dialogRef.current?.getBoundingClientRect()
49+
if (!rect) return
50+
const isClickOutside =
51+
e.clientX < rect.left ||
52+
e.clientX > rect.right ||
53+
e.clientY < rect.top ||
54+
e.clientY > rect.bottom
55+
if (isClickOutside) {
56+
onClose()
8357
}
58+
}
8459

85-
document.addEventListener('keydown', handleKeyDown)
86-
return () => document.removeEventListener('keydown', handleKeyDown)
87-
}, [isOpen, onClose])
60+
const handleCancel = (e: React.SyntheticEvent<HTMLDialogElement>) => {
61+
e.preventDefault()
62+
onClose()
63+
}
8864

89-
// Focus management
90-
useEffect(() => {
91-
if (isOpen && modalRef.current) {
92-
const focusableElements = modalRef.current.querySelectorAll(
93-
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
94-
)
95-
const firstElement = focusableElements[0] as HTMLElement
96-
firstElement?.focus()
97-
}
98-
}, [isOpen])
99-
100-
const modalBoxClasses = `
101-
modal-box overflow-hidden rounded-xl md:rounded-2xl p-3 md:p-4 shadow-xl transition-all duration-200
102-
${sizeValue.w} ${sizeValue.minH} ${size === 'full' ? sizeValue.h : ''} ${className}
103-
`
104-
105-
if (!isOpen) return null
65+
const sizeClass = sizeClasses[size] || sizeClasses.md
10666

10767
return createPortal(
10868
<dialog
109-
open={isOpen}
69+
ref={dialogRef}
11070
dir={direction}
111-
aria-labelledby={typeof title === 'string' ? title : 'modal-title'}
112-
aria-modal="true"
113-
onClick={() => closeOnBackdropClick && onClose()}
114-
className="flex items-center justify-center p-2 transition-opacity duration-200 opacity-100 modal modal-middle md:p-4"
71+
onCancel={handleCancel}
72+
onClick={handleBackdropClick}
73+
className="modal"
11574
>
11675
<div
117-
ref={modalRef}
118-
onClick={(e) => e.stopPropagation()}
119-
className={`${modalBoxClasses} animate-modal-in`}
76+
className={`
77+
modal-box
78+
rounded-xl md:rounded-2xl
79+
p-3 md:p-4
80+
shadow-xl
81+
overflow-hidden
82+
${sizeClass}
83+
${className}
84+
`}
12085
>
12186
{(title || showCloseButton) && (
12287
<div className="flex items-center justify-between gap-2 mb-2 md:mb-3 md:gap-4">
12388
{title && (
124-
<h3
125-
id="modal-title"
126-
className="text-base font-semibold md:text-lg"
127-
>
89+
<h3 className="text-base font-semibold md:text-lg">
12890
{title}
12991
</h3>
13092
)}
13193
{showCloseButton && (
13294
<button
13395
type="button"
13496
onClick={onClose}
135-
className="flex items-center justify-center transition-all rounded-full cursor-pointer w-7 h-7 md:w-8 md:h-8 bg-base-300 text-muted hover:bg-base-content/10 hover:scale-105 active:scale-95 shrink-0 outline-0! border-0!"
97+
className="min-h-0 p-0 rounded-full btn btn-sm btn-ghost w-7 h-7 md:w-8 md:h-8 text-base-content/60 hover:text-base-content hover:bg-base-content/10"
13698
aria-label="Close modal"
13799
>
138-
<IoClose />
100+
<IoClose className="w-5 h-5" />
139101
</button>
140102
)}
141103
</div>
142104
)}
143105
<div
144-
className={`overflow-y-auto overflow-x-hidden ${size !== 'full' ? sizeValue.h : 'h-full'} pr-0.5 md:pr-1`}
106+
className={`
107+
overflow-y-auto overflow-x-hidden
108+
pr-0.5 md:pr-1
109+
${size !== 'full' ? 'max-h-[70vh]' : 'max-h-[85vh]'}
110+
`}
145111
>
146112
{children}
147113
</div>

src/renderer/component/modals/network-options.component.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export function NetworkOptionsModalComponent(props: Props) {
7373
onChange={(value) =>
7474
setNetworkInterfaceInterface(value.target.value)
7575
}
76-
className="px-2 select"
76+
className="border cursor-pointer select rounded-xl bg-base-200 border-base-300 outline-primary/30"
7777
>
7878
{networkAdapters.map((item) => (
7979
<option value={item} selected={item === network} key={item}>

0 commit comments

Comments
 (0)