diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx index ec48a85..9ccfd1c 100644 --- a/src/app/dashboard/page.tsx +++ b/src/app/dashboard/page.tsx @@ -1,6 +1,6 @@ import { requireAuth } from '@/lib/auth/server'; import { getServers } from '@/lib/api/server/servers'; -import { hasPermission } from '@/lib/types'; +import { hasPermission } from '@/lib/schemas'; import Link from 'next/link'; import { ServerListWithActions } from '@/components/server/ServerListWithActions'; import { SteamCMDNotification } from '@/components/ui/SteamCMDNotification'; diff --git a/src/app/dashboard/server/[id]/page.tsx b/src/app/dashboard/server/[id]/page.tsx index d64cb0a..b27480b 100644 --- a/src/app/dashboard/server/[id]/page.tsx +++ b/src/app/dashboard/server/[id]/page.tsx @@ -22,7 +22,7 @@ export default async function ServerPage({ params }: ServerPageProps) { const [server, configurations, statistics] = await Promise.all([ getServer(session.token!, id), getServerConfigurations(session.token!, id), - getServerStatistics(session.token!, id, startDate, endDate) + getServerStatistics(session.token!, id, { startDate, endDate }) ]); return ( diff --git a/src/components/configuration/AssistRulesEditor.tsx b/src/components/configuration/AssistRulesEditor.tsx index 18085e4..190bc19 100644 --- a/src/components/configuration/AssistRulesEditor.tsx +++ b/src/components/configuration/AssistRulesEditor.tsx @@ -1,7 +1,7 @@ 'use client'; import { useState } from 'react'; -import type { AssistRules } from '@/lib/types/config'; +import type { AssistRules } from '@/lib/schemas/config'; import { updateAssistRulesAction } from '@/lib/actions/configuration'; interface AssistRulesEditorProps { @@ -9,6 +9,54 @@ interface AssistRulesEditorProps { config: AssistRules; } +const assistFields = [ + { + key: 'stabilityControlLevelMax' as keyof AssistRules, + label: 'Stability Control Level Max', + type: 'number' + }, + { + key: 'disableAutosteer' as keyof AssistRules, + label: 'Disable Autosteer', + type: 'select' + }, + { + key: 'disableAutoLights' as keyof AssistRules, + label: 'Disable Auto Lights', + type: 'select' + }, + { + key: 'disableAutoWiper' as keyof AssistRules, + label: 'Disable Auto Wiper', + type: 'select' + }, + { + key: 'disableAutoEngineStart' as keyof AssistRules, + label: 'Disable Auto Engine Start', + type: 'select' + }, + { + key: 'disableAutoPitLimiter' as keyof AssistRules, + label: 'Disable Auto Pit Limiter', + type: 'select' + }, + { + key: 'disableAutoGear' as keyof AssistRules, + label: 'Disable Auto Gear', + type: 'select' + }, + { + key: 'disableAutoClutch' as keyof AssistRules, + label: 'Disable Auto Clutch', + type: 'select' + }, + { + key: 'disableIdealLine' as keyof AssistRules, + label: 'Disable Ideal Line', + type: 'select' + } +]; + export function AssistRulesEditor({ serverId, config }: AssistRulesEditorProps) { const [formData, setFormData] = useState(config); const [restart, setRestart] = useState(true); @@ -43,54 +91,6 @@ export function AssistRulesEditor({ serverId, config }: AssistRulesEditorProps) })); }; - const assistFields = [ - { - key: 'stabilityControlLevelMax' as keyof AssistRules, - label: 'Stability Control Level Max', - type: 'number' - }, - { - key: 'disableAutosteer' as keyof AssistRules, - label: 'Disable Autosteer', - type: 'select' - }, - { - key: 'disableAutoLights' as keyof AssistRules, - label: 'Disable Auto Lights', - type: 'select' - }, - { - key: 'disableAutoWiper' as keyof AssistRules, - label: 'Disable Auto Wiper', - type: 'select' - }, - { - key: 'disableAutoEngineStart' as keyof AssistRules, - label: 'Disable Auto Engine Start', - type: 'select' - }, - { - key: 'disableAutoPitLimiter' as keyof AssistRules, - label: 'Disable Auto Pit Limiter', - type: 'select' - }, - { - key: 'disableAutoGear' as keyof AssistRules, - label: 'Disable Auto Gear', - type: 'select' - }, - { - key: 'disableAutoClutch' as keyof AssistRules, - label: 'Disable Auto Clutch', - type: 'select' - }, - { - key: 'disableIdealLine' as keyof AssistRules, - label: 'Disable Ideal Line', - type: 'select' - } - ]; - return (
diff --git a/src/components/configuration/ConfigurationEditor.tsx b/src/components/configuration/ConfigurationEditor.tsx index 64149f7..95766e7 100644 --- a/src/components/configuration/ConfigurationEditor.tsx +++ b/src/components/configuration/ConfigurationEditor.tsx @@ -1,7 +1,7 @@ 'use client'; import { useState } from 'react'; -import type { Configuration } from '@/lib/types/config'; +import type { Configuration } from '@/lib/schemas/config'; import { updateConfigurationAction } from '@/lib/actions/configuration'; interface ConfigurationEditorProps { diff --git a/src/components/configuration/EventConfigEditor.tsx b/src/components/configuration/EventConfigEditor.tsx index 464c9e4..d6463be 100644 --- a/src/components/configuration/EventConfigEditor.tsx +++ b/src/components/configuration/EventConfigEditor.tsx @@ -1,7 +1,7 @@ 'use client'; import { useState } from 'react'; -import type { EventConfig, Session } from '@/lib/types/config'; +import type { EventConfig, Session } from '@/lib/schemas/config'; import { updateEventConfigAction } from '@/lib/actions/configuration'; interface EventConfigEditorProps { @@ -9,6 +9,12 @@ interface EventConfigEditorProps { config: EventConfig; } +const sessionTypes = [ + { value: 'P', label: 'Practice' }, + { value: 'Q', label: 'Qualifying' }, + { value: 'R', label: 'Race' } +]; + export function EventConfigEditor({ serverId, config }: EventConfigEditorProps) { const [formData, setFormData] = useState(config); const [restart, setRestart] = useState(true); @@ -90,12 +96,6 @@ export function EventConfigEditor({ serverId, config }: EventConfigEditorProps) })); }; - const sessionTypes = [ - { value: 'P', label: 'Practice' }, - { value: 'Q', label: 'Qualifying' }, - { value: 'R', label: 'Race' } - ]; - return (
diff --git a/src/components/configuration/EventRulesEditor.tsx b/src/components/configuration/EventRulesEditor.tsx index a8a8a14..1b9e466 100644 --- a/src/components/configuration/EventRulesEditor.tsx +++ b/src/components/configuration/EventRulesEditor.tsx @@ -1,7 +1,7 @@ 'use client'; import { useState } from 'react'; -import type { EventRules } from '@/lib/types/config'; +import type { EventRules } from '@/lib/schemas/config'; import { updateEventRulesAction } from '@/lib/actions/configuration'; interface EventRulesEditorProps { @@ -9,6 +9,65 @@ interface EventRulesEditorProps { config: EventRules; } +const numberFields = [ + { + key: 'qualifyStandingType' as keyof EventRules, + label: 'Qualify Standing Type', + min: -1, + max: 1 + }, + { + key: 'pitWindowLengthSec' as keyof EventRules, + label: 'Pit Window Length (seconds)', + min: -1 + }, + { + key: 'driverStintTimeSec' as keyof EventRules, + label: 'Driver Stint Time (seconds)', + min: -1 + }, + { + key: 'mandatoryPitstopCount' as keyof EventRules, + label: 'Mandatory Pitstop Count', + min: -1, + max: 5 + }, + { + key: 'maxTotalDrivingTime' as keyof EventRules, + label: 'Max Total Driving Time (seconds)', + min: -1 + }, + { + key: 'tyreSetCount' as keyof EventRules, + label: 'Tyre Set Count', + min: 0, + max: 50 + } +]; + +const booleanFields = [ + { + key: 'isRefuellingAllowedInRace' as keyof EventRules, + label: 'Refuelling Allowed in Race' + }, + { + key: 'isRefuellingTimeFixed' as keyof EventRules, + label: 'Refuelling Time Fixed' + }, + { + key: 'isMandatoryPitstopRefuellingRequired' as keyof EventRules, + label: 'Mandatory Pitstop Refuelling Required' + }, + { + key: 'isMandatoryPitstopTyreChangeRequired' as keyof EventRules, + label: 'Mandatory Pitstop Tyre Change Required' + }, + { + key: 'isMandatoryPitstopSwapDriverRequired' as keyof EventRules, + label: 'Mandatory Pitstop Swap Driver Required' + } +]; + export function EventRulesEditor({ serverId, config }: EventRulesEditorProps) { const [formData, setFormData] = useState(config); const [restart, setRestart] = useState(true); @@ -43,65 +102,6 @@ export function EventRulesEditor({ serverId, config }: EventRulesEditorProps) { })); }; - const numberFields = [ - { - key: 'qualifyStandingType' as keyof EventRules, - label: 'Qualify Standing Type', - min: -1, - max: 1 - }, - { - key: 'pitWindowLengthSec' as keyof EventRules, - label: 'Pit Window Length (seconds)', - min: -1 - }, - { - key: 'driverStintTimeSec' as keyof EventRules, - label: 'Driver Stint Time (seconds)', - min: -1 - }, - { - key: 'mandatoryPitstopCount' as keyof EventRules, - label: 'Mandatory Pitstop Count', - min: -1, - max: 5 - }, - { - key: 'maxTotalDrivingTime' as keyof EventRules, - label: 'Max Total Driving Time (seconds)', - min: -1 - }, - { - key: 'tyreSetCount' as keyof EventRules, - label: 'Tyre Set Count', - min: 0, - max: 50 - } - ]; - - const booleanFields = [ - { - key: 'isRefuellingAllowedInRace' as keyof EventRules, - label: 'Refuelling Allowed in Race' - }, - { - key: 'isRefuellingTimeFixed' as keyof EventRules, - label: 'Refuelling Time Fixed' - }, - { - key: 'isMandatoryPitstopRefuellingRequired' as keyof EventRules, - label: 'Mandatory Pitstop Refuelling Required' - }, - { - key: 'isMandatoryPitstopTyreChangeRequired' as keyof EventRules, - label: 'Mandatory Pitstop Tyre Change Required' - }, - { - key: 'isMandatoryPitstopSwapDriverRequired' as keyof EventRules, - label: 'Mandatory Pitstop Swap Driver Required' - } - ]; - return (
diff --git a/src/components/configuration/ServerSettingsEditor.tsx b/src/components/configuration/ServerSettingsEditor.tsx index 152b0fd..0247255 100644 --- a/src/components/configuration/ServerSettingsEditor.tsx +++ b/src/components/configuration/ServerSettingsEditor.tsx @@ -1,7 +1,7 @@ 'use client'; import { useState } from 'react'; -import type { ServerSettings } from '@/lib/types/config'; +import type { ServerSettings } from '@/lib/schemas/config'; import { updateServerSettingsAction } from '@/lib/actions/configuration'; interface ServerSettingsEditorProps { @@ -9,6 +9,84 @@ interface ServerSettingsEditorProps { config: ServerSettings; } +const textFields = [ + { + key: 'serverName' as keyof ServerSettings, + label: 'Server Name', + type: 'text' + }, + { + key: 'adminPassword' as keyof ServerSettings, + label: 'Admin Password', + type: 'password' + }, + { + key: 'password' as keyof ServerSettings, + label: 'Password', + type: 'password' + }, + { + key: 'spectatorPassword' as keyof ServerSettings, + label: 'Spectator Password', + type: 'password' + }, + { + key: 'centralEntryListPath' as keyof ServerSettings, + label: 'Central Entry List Path', + type: 'text' + } +]; + +const carGroups = ['FreeForAll', 'GT3', 'GT4', 'GT2', 'GTC', 'TCX']; + +const numberFields = [ + { + key: 'trackMedalsRequirement' as keyof ServerSettings, + label: 'Track Medals Requirement', + min: -1, + max: 3 + }, + { + key: 'safetyRatingRequirement' as keyof ServerSettings, + label: 'Safety Rating Requirement', + min: -1, + max: 99 + }, + { + key: 'racecraftRatingRequirement' as keyof ServerSettings, + label: 'Racecraft Rating Requirement', + min: -1, + max: 99 + }, + { + key: 'maxCarSlots' as keyof ServerSettings, + label: 'Max Car Slots', + min: 1, + max: 30 + } +]; + +const selectFields = [ + { + key: 'dumpLeaderboards' as keyof ServerSettings, + label: 'Dump Leaderboards' + }, + { key: 'isRaceLocked' as keyof ServerSettings, label: 'Race Locked' }, + { + key: 'randomizeTrackWhenEmpty' as keyof ServerSettings, + label: 'Randomize Track When Empty' + }, + { key: 'allowAutoDQ' as keyof ServerSettings, label: 'Allow Auto DQ' }, + { + key: 'shortFormationLap' as keyof ServerSettings, + label: 'Short Formation Lap' + }, + { + key: 'ignorePrematureDisconnects' as keyof ServerSettings, + label: 'Ignore Premature Disconnects' + } +]; + export function ServerSettingsEditor({ serverId, config }: ServerSettingsEditorProps) { const [formData, setFormData] = useState(config); const [restart, setRestart] = useState(true); @@ -43,84 +121,6 @@ export function ServerSettingsEditor({ serverId, config }: ServerSettingsEditorP })); }; - const textFields = [ - { - key: 'serverName' as keyof ServerSettings, - label: 'Server Name', - type: 'text' - }, - { - key: 'adminPassword' as keyof ServerSettings, - label: 'Admin Password', - type: 'password' - }, - { - key: 'password' as keyof ServerSettings, - label: 'Password', - type: 'password' - }, - { - key: 'spectatorPassword' as keyof ServerSettings, - label: 'Spectator Password', - type: 'password' - }, - { - key: 'centralEntryListPath' as keyof ServerSettings, - label: 'Central Entry List Path', - type: 'text' - } - ]; - - const carGroups = ['FreeForAll', 'GT3', 'GT4', 'GT2', 'GTC', 'TCX']; - - const numberFields = [ - { - key: 'trackMedalsRequirement' as keyof ServerSettings, - label: 'Track Medals Requirement', - min: -1, - max: 3 - }, - { - key: 'safetyRatingRequirement' as keyof ServerSettings, - label: 'Safety Rating Requirement', - min: -1, - max: 99 - }, - { - key: 'racecraftRatingRequirement' as keyof ServerSettings, - label: 'Racecraft Rating Requirement', - min: -1, - max: 99 - }, - { - key: 'maxCarSlots' as keyof ServerSettings, - label: 'Max Car Slots', - min: 1, - max: 30 - } - ]; - - const selectFields = [ - { - key: 'dumpLeaderboards' as keyof ServerSettings, - label: 'Dump Leaderboards' - }, - { key: 'isRaceLocked' as keyof ServerSettings, label: 'Race Locked' }, - { - key: 'randomizeTrackWhenEmpty' as keyof ServerSettings, - label: 'Randomize Track When Empty' - }, - { key: 'allowAutoDQ' as keyof ServerSettings, label: 'Allow Auto DQ' }, - { - key: 'shortFormationLap' as keyof ServerSettings, - label: 'Short Formation Lap' - }, - { - key: 'ignorePrematureDisconnects' as keyof ServerSettings, - label: 'Ignore Premature Disconnects' - } - ]; - return (
diff --git a/src/components/membership/CreateUserModal.tsx b/src/components/membership/CreateUserModal.tsx index cbb7123..7222004 100644 --- a/src/components/membership/CreateUserModal.tsx +++ b/src/components/membership/CreateUserModal.tsx @@ -1,7 +1,7 @@ 'use client'; import { useState } from 'react'; -import type { Role } from '@/lib/types'; +import type { Role } from '@/lib/schemas'; import { createUserAction } from '@/lib/actions/membership'; interface CreateUserModalProps { diff --git a/src/components/membership/DeleteUserModal.tsx b/src/components/membership/DeleteUserModal.tsx index edc52ef..06d0442 100644 --- a/src/components/membership/DeleteUserModal.tsx +++ b/src/components/membership/DeleteUserModal.tsx @@ -1,7 +1,7 @@ 'use client'; import { useState } from 'react'; -import type { User } from '@/lib/types'; +import type { User } from '@/lib/schemas'; import { deleteUserAction } from '@/lib/actions/membership'; interface DeleteUserModalProps { diff --git a/src/components/membership/UserManagementTable.tsx b/src/components/membership/UserManagementTable.tsx index cb2e6fe..9500bb1 100644 --- a/src/components/membership/UserManagementTable.tsx +++ b/src/components/membership/UserManagementTable.tsx @@ -3,8 +3,8 @@ import { useState } from 'react'; import Link from 'next/link'; import { useRouter } from 'next/navigation'; -import type { Role, User } from '@/lib/types'; -import { hasPermission } from '@/lib/types/user'; +import type { Role, User } from '@/lib/schemas'; +import { hasPermission } from '@/lib/schemas/user'; import { CreateUserModal } from './CreateUserModal'; import { DeleteUserModal } from './DeleteUserModal'; diff --git a/src/components/server/DeleteServerModal.tsx b/src/components/server/DeleteServerModal.tsx index 38138ae..3b6d0b5 100644 --- a/src/components/server/DeleteServerModal.tsx +++ b/src/components/server/DeleteServerModal.tsx @@ -4,7 +4,7 @@ import { useState, useTransition } from 'react'; import { Modal } from '@/components/ui/Modal'; import { LoadingSpinner } from '@/components/ui/LoadingSpinner'; import { deleteServerAction } from '@/lib/actions/server-management'; -import { Server } from '@/lib/types/server'; +import { Server } from '@/lib/schemas/server'; interface DeleteServerModalProps { isOpen: boolean; diff --git a/src/components/server/ServerCard.tsx b/src/components/server/ServerCard.tsx index 3c88a43..8a68653 100644 --- a/src/components/server/ServerCard.tsx +++ b/src/components/server/ServerCard.tsx @@ -1,6 +1,6 @@ import Link from 'next/link'; import { useTransition } from 'react'; -import { Server, ServiceStatus, getStatusColor, serviceStatusToString } from '@/lib/types'; +import { Server, ServiceStatus, getStatusColor, serviceStatusToString } from '@/lib/schemas'; import { startServerEventAction, restartServerEventAction, diff --git a/src/components/server/ServerConfigurationTabs.tsx b/src/components/server/ServerConfigurationTabs.tsx index 52c2fb0..7aafae2 100644 --- a/src/components/server/ServerConfigurationTabs.tsx +++ b/src/components/server/ServerConfigurationTabs.tsx @@ -1,6 +1,6 @@ 'use client'; -import { Configurations, ServerTab } from '@/lib/types/config'; +import { Configurations, ServerTab } from '@/lib/schemas/config'; import { ConfigurationEditor } from '@/components/configuration/ConfigurationEditor'; import { AssistRulesEditor } from '@/components/configuration/AssistRulesEditor'; import { EventConfigEditor } from '@/components/configuration/EventConfigEditor'; @@ -8,13 +8,21 @@ import { EventRulesEditor } from '@/components/configuration/EventRulesEditor'; import { ServerSettingsEditor } from '@/components/configuration/ServerSettingsEditor'; import { StatisticsDashboard } from '@/components/statistics/StatisticsDashboard'; import { useState } from 'react'; -import { StateHistoryStats } from '@/lib/types'; +import { StateHistoryStats } from '@/lib/schemas'; interface ServerConfigurationTabsProps { serverId: string; configurations: Configurations; statistics: StateHistoryStats; } +const tabs = [ + { id: ServerTab.statistics, name: 'Statistics', icon: '📊' }, + { id: ServerTab.configuration, name: 'Configuration', icon: '⚙️' }, + { id: ServerTab.assistRules, name: 'Assist Rules', icon: '🚗' }, + { id: ServerTab.event, name: 'Event Config', icon: '🏁' }, + { id: ServerTab.eventRules, name: 'Event Rules', icon: '📋' }, + { id: ServerTab.settings, name: 'Server Settings', icon: '🔧' } +]; export function ServerConfigurationTabs({ serverId, @@ -22,14 +30,6 @@ export function ServerConfigurationTabs({ statistics }: ServerConfigurationTabsProps) { const [currentTab, setCurrentTab] = useState(ServerTab.statistics); - const tabs = [ - { id: ServerTab.statistics, name: 'Statistics', icon: '📊' }, - { id: ServerTab.configuration, name: 'Configuration', icon: '⚙️' }, - { id: ServerTab.assistRules, name: 'Assist Rules', icon: '🚗' }, - { id: ServerTab.event, name: 'Event Config', icon: '🏁' }, - { id: ServerTab.eventRules, name: 'Event Rules', icon: '📋' }, - { id: ServerTab.settings, name: 'Server Settings', icon: '🔧' } - ]; const renderTabContent = () => { switch (currentTab) { diff --git a/src/components/server/ServerCreationPopup.tsx b/src/components/server/ServerCreationPopup.tsx index 2a430b1..08fb79b 100644 --- a/src/components/server/ServerCreationPopup.tsx +++ b/src/components/server/ServerCreationPopup.tsx @@ -2,13 +2,13 @@ import { useEffect, useRef, useState, useCallback } from 'react'; import { useWebSocket } from '@/lib/websocket/context'; -import { +import type { WebSocketMessage, StepData, SteamOutputData, ErrorData, CompleteData -} from '@/lib/websocket/client'; +} from '@/lib/schemas/websocket'; interface ServerCreationPopupProps { serverId: string; diff --git a/src/components/server/ServerHeader.tsx b/src/components/server/ServerHeader.tsx index af34375..78c56df 100644 --- a/src/components/server/ServerHeader.tsx +++ b/src/components/server/ServerHeader.tsx @@ -1,12 +1,12 @@ 'use client'; import Link from 'next/link'; -import { Server, getStatusColor, serviceStatusToString, ServiceStatus } from '@/lib/types/server'; +import { Server, getStatusColor, serviceStatusToString, ServiceStatus } from '@/lib/schemas/server'; import { startServerEventAction, restartServerEventAction, stopServerEventAction } from '@/lib/actions/servers'; -import { hasPermission, User } from '@/lib/types'; +import { hasPermission, User } from '@/lib/schemas'; import { useState, useTransition } from 'react'; import { useRouter } from 'next/navigation'; import { DeleteServerModal } from './DeleteServerModal'; diff --git a/src/components/server/ServerListWithActions.tsx b/src/components/server/ServerListWithActions.tsx index ef8ee2f..08a2e75 100644 --- a/src/components/server/ServerListWithActions.tsx +++ b/src/components/server/ServerListWithActions.tsx @@ -1,8 +1,8 @@ 'use client'; import { useCallback, useState } from 'react'; -import { Server } from '@/lib/types/server'; -import { User, hasPermission } from '@/lib/types/user'; +import { Server } from '@/lib/schemas/server'; +import { User, hasPermission } from '@/lib/schemas/user'; import { ServerCard } from './ServerCard'; import { CreateServerModal } from './CreateServerModal'; import RefreshButton from '@/components/ui/RefreshButton'; diff --git a/src/components/statistics/SessionTypesChart.tsx b/src/components/statistics/SessionTypesChart.tsx index 55f6ba0..3ba5e23 100644 --- a/src/components/statistics/SessionTypesChart.tsx +++ b/src/components/statistics/SessionTypesChart.tsx @@ -14,16 +14,16 @@ interface SessionTypesChartProps { data: SessionCount[]; } -export function SessionTypesChart({ data }: SessionTypesChartProps) { - const colors = [ - '#3b82f6', // blue - '#10b981', // emerald - '#f59e0b', // amber - '#ef4444', // red - '#8b5cf6', // violet - '#06b6d4' // cyan - ]; +const colors = [ + '#3b82f6', // blue + '#10b981', // emerald + '#f59e0b', // amber + '#ef4444', // red + '#8b5cf6', // violet + '#06b6d4' // cyan +]; +export function SessionTypesChart({ data }: SessionTypesChartProps) { const chartData = { labels: data.map((item) => item.name), datasets: [ diff --git a/src/components/statistics/StatisticsDashboard.tsx b/src/components/statistics/StatisticsDashboard.tsx index ab9efda..498f781 100644 --- a/src/components/statistics/StatisticsDashboard.tsx +++ b/src/components/statistics/StatisticsDashboard.tsx @@ -1,6 +1,6 @@ 'use client'; -import type { StateHistoryStats } from '@/lib/types/statistics'; +import type { StateHistoryStats } from '@/lib/schemas/statistics'; import { PlayerCountChart } from './PlayerCountChart'; import { SessionTypesChart } from './SessionTypesChart'; import { DailyActivityChart } from './DailyActivityChart'; diff --git a/src/components/ui/Button.tsx b/src/components/ui/Button.tsx index 67f3ffb..0691188 100644 --- a/src/components/ui/Button.tsx +++ b/src/components/ui/Button.tsx @@ -8,27 +8,27 @@ interface ButtonProps extends ButtonHTMLAttributes { isLoading?: boolean; } +const baseClasses = + 'inline-flex items-center justify-center font-medium rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed'; + +const variants = { + primary: 'bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500', + secondary: 'bg-gray-600 text-white hover:bg-gray-700 focus:ring-gray-500', + danger: 'bg-red-600 text-white hover:bg-red-700 focus:ring-red-500', + ghost: 'text-gray-300 hover:text-white hover:bg-gray-700 focus:ring-gray-500' +}; + +const sizes = { + sm: 'px-3 py-1 text-sm', + md: 'px-4 py-2 text-sm', + lg: 'px-6 py-3 text-base' +}; + export const Button = forwardRef( ( { className, variant = 'primary', size = 'md', isLoading, children, disabled, ...props }, ref ) => { - const baseClasses = - 'inline-flex items-center justify-center font-medium rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed'; - - const variants = { - primary: 'bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500', - secondary: 'bg-gray-600 text-white hover:bg-gray-700 focus:ring-gray-500', - danger: 'bg-red-600 text-white hover:bg-red-700 focus:ring-red-500', - ghost: 'text-gray-300 hover:text-white hover:bg-gray-700 focus:ring-gray-500' - }; - - const sizes = { - sm: 'px-3 py-1 text-sm', - md: 'px-4 py-2 text-sm', - lg: 'px-6 py-3 text-base' - }; - return (