Add files via upload
This commit is contained in:
9
frontend/src/components/UI/Badge.jsx
Normal file
9
frontend/src/components/UI/Badge.jsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import { STATUS_COLORS, getStatusLabel } from '../../utils/statusHelpers'
|
||||
export default function Badge({ status }) {
|
||||
const c = STATUS_COLORS[status] || STATUS_COLORS.upcoming
|
||||
return (
|
||||
<span className={`inline-flex items-center px-2 py-0.5 rounded text-[10px] font-semibold border ${c.bg} ${c.text} ${c.border}`}>
|
||||
{getStatusLabel(status)}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
16
frontend/src/components/UI/Button.jsx
Normal file
16
frontend/src/components/UI/Button.jsx
Normal file
@@ -0,0 +1,16 @@
|
||||
export default function Button({ children, variant='primary', size='md', onClick, type='button', disabled=false, className='' }) {
|
||||
const base = 'font-medium rounded transition-all duration-150 focus:outline-none focus:ring-2 focus:ring-gold/50 disabled:opacity-50 disabled:cursor-not-allowed'
|
||||
const variants = {
|
||||
primary: 'bg-gold text-surface hover:bg-gold-light',
|
||||
secondary: 'bg-surface-elevated border border-surface-border text-text-primary hover:border-gold hover:text-gold',
|
||||
danger: 'bg-red-500/20 border border-red-500/30 text-red-400 hover:bg-red-500/30',
|
||||
ghost: 'text-text-muted hover:text-gold hover:bg-surface-elevated',
|
||||
}
|
||||
const sizes = { sm: 'px-3 py-1.5 text-xs', md: 'px-4 py-2 text-sm', lg: 'px-6 py-2.5 text-base' }
|
||||
return (
|
||||
<button type={type} onClick={onClick} disabled={disabled}
|
||||
className={`${base} ${variants[variant]} ${sizes[size]} ${className}`}>
|
||||
{children}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
24
frontend/src/components/UI/Drawer.jsx
Normal file
24
frontend/src/components/UI/Drawer.jsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import { useEffect } from 'react'
|
||||
export default function Drawer({ isOpen, onClose, children }) {
|
||||
useEffect(() => {
|
||||
const h = (e) => { if (e.key === 'Escape') onClose() }
|
||||
if (isOpen) document.addEventListener('keydown', h)
|
||||
return () => document.removeEventListener('keydown', h)
|
||||
}, [isOpen, onClose])
|
||||
return (
|
||||
<>
|
||||
{isOpen && <div className="fixed inset-0 z-40 bg-black/50 backdrop-blur-sm" onClick={onClose} />}
|
||||
<div
|
||||
className={`fixed bottom-0 left-0 right-0 z-50 bg-surface-raised border-t border-surface-border rounded-t-2xl shadow-2xl transition-transform duration-300 ease-in-out ${isOpen ? 'translate-y-0' : 'translate-y-full'}`}
|
||||
style={{ maxHeight: '65vh' }}
|
||||
>
|
||||
<div className="relative flex items-center justify-between px-6 py-3 border-b border-surface-border">
|
||||
<div className="absolute left-1/2 -translate-x-1/2 top-2 w-10 h-1 bg-surface-border rounded-full" />
|
||||
<div className="flex-1" />
|
||||
<button onClick={onClose} className="text-text-muted hover:text-gold transition-colors text-lg">✕</button>
|
||||
</div>
|
||||
<div className="overflow-y-auto" style={{ maxHeight: 'calc(65vh - 52px)' }}>{children}</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
22
frontend/src/components/UI/Modal.jsx
Normal file
22
frontend/src/components/UI/Modal.jsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { useEffect } from 'react'
|
||||
export default function Modal({ isOpen, onClose, title, children, size='md' }) {
|
||||
useEffect(() => {
|
||||
const h = (e) => { if (e.key === 'Escape') onClose() }
|
||||
if (isOpen) document.addEventListener('keydown', h)
|
||||
return () => document.removeEventListener('keydown', h)
|
||||
}, [isOpen, onClose])
|
||||
if (!isOpen) return null
|
||||
const sizes = { sm:'max-w-md', md:'max-w-lg', lg:'max-w-2xl', xl:'max-w-4xl' }
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center">
|
||||
<div className="absolute inset-0 bg-black/70 backdrop-blur-sm" onClick={onClose} />
|
||||
<div className={`relative w-full ${sizes[size]} mx-4 bg-surface-raised border border-surface-border rounded-xl shadow-2xl`}>
|
||||
<div className="flex items-center justify-between px-6 py-4 border-b border-surface-border">
|
||||
<h2 className="text-lg font-semibold text-gold">{title}</h2>
|
||||
<button onClick={onClose} className="text-text-muted hover:text-text-primary transition-colors text-xl leading-none">✕</button>
|
||||
</div>
|
||||
<div className="px-6 py-5 overflow-y-auto max-h-[80vh]">{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user