Initial changes

This commit is contained in:
Tickbase
2025-05-18 08:06:56 +02:00
parent 19087c00da
commit 0be15f83e7
82 changed files with 4636 additions and 3237 deletions

View File

@@ -0,0 +1,59 @@
import { FC } from 'react'
import Button, { ButtonVariant } from '../buttons/Button'
// Define available action types
export type ActionType = 'install_cream' | 'uninstall_cream' | 'install_smoke' | 'uninstall_smoke'
interface ActionButtonProps {
action: ActionType
isInstalled: boolean
isWorking: boolean
onClick: () => void
disabled?: boolean
className?: string
}
/**
* Specialized button for game installation actions
*/
const ActionButton: FC<ActionButtonProps> = ({
action,
isInstalled,
isWorking,
onClick,
disabled = false,
className = '',
}) => {
// Determine button text based on state
const getButtonText = () => {
if (isWorking) return 'Working...'
const isCream = action.includes('cream')
const product = isCream ? 'CreamLinux' : 'SmokeAPI'
return isInstalled ? `Uninstall ${product}` : `Install ${product}`
}
// Map to our button variant
const getButtonVariant = (): ButtonVariant => {
// For uninstall actions, use danger variant
if (isInstalled) return 'danger'
// For install actions, use success variant
return 'success'
}
return (
<Button
variant={getButtonVariant()}
isLoading={isWorking}
onClick={onClick}
disabled={disabled || isWorking}
fullWidth
className={`action-button ${className}`}
>
{getButtonText()}
</Button>
)
}
export default ActionButton

View File

@@ -0,0 +1,52 @@
interface AnimatedCheckboxProps {
checked: boolean;
onChange: () => void;
label?: string;
sublabel?: string;
className?: string;
}
/**
* Animated checkbox component with optional label and sublabel
*/
const AnimatedCheckbox = ({
checked,
onChange,
label,
sublabel,
className = '',
}: AnimatedCheckboxProps) => {
return (
<label className={`animated-checkbox ${className}`}>
<input
type="checkbox"
checked={checked}
onChange={onChange}
className="checkbox-original"
/>
<span className={`checkbox-custom ${checked ? 'checked' : ''}`}>
<svg viewBox="0 0 24 24" className="checkmark-icon" aria-hidden="true">
<path
className={`checkmark ${checked ? 'checked' : ''}`}
d="M5 12l5 5L20 7"
stroke="#fff"
strokeWidth="2.5"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
</span>
{(label || sublabel) && (
<div className="checkbox-content">
{label && <span className="checkbox-label">{label}</span>}
{sublabel && <span className="checkbox-sublabel">{sublabel}</span>}
</div>
)}
</label>
)
}
export default AnimatedCheckbox

View File

@@ -0,0 +1,67 @@
import { FC, ButtonHTMLAttributes } from 'react';
export type ButtonVariant = 'primary' | 'secondary' | 'danger' | 'success' | 'warning';
export type ButtonSize = 'small' | 'medium' | 'large';
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
variant?: ButtonVariant;
size?: ButtonSize;
isLoading?: boolean;
leftIcon?: React.ReactNode;
rightIcon?: React.ReactNode;
fullWidth?: boolean;
}
/**
* Button component with different variants, sizes and states
*/
const Button: FC<ButtonProps> = ({
children,
variant = 'primary',
size = 'medium',
isLoading = false,
leftIcon,
rightIcon,
fullWidth = false,
className = '',
disabled,
...props
}) => {
// Size class mapping
const sizeClass = {
small: 'btn-sm',
medium: 'btn-md',
large: 'btn-lg',
}[size];
// Variant class mapping
const variantClass = {
primary: 'btn-primary',
secondary: 'btn-secondary',
danger: 'btn-danger',
success: 'btn-success',
warning: 'btn-warning',
}[variant];
return (
<button
className={`btn ${variantClass} ${sizeClass} ${fullWidth ? 'btn-full' : ''} ${
isLoading ? 'btn-loading' : ''
} ${className}`}
disabled={disabled || isLoading}
{...props}
>
{isLoading && (
<span className="btn-spinner">
<span className="spinner"></span>
</span>
)}
{leftIcon && !isLoading && <span className="btn-icon btn-icon-left">{leftIcon}</span>}
<span className="btn-text">{children}</span>
{rightIcon && !isLoading && <span className="btn-icon btn-icon-right">{rightIcon}</span>}
</button>
);
};
export default Button;

View File

@@ -0,0 +1,8 @@
// Export all button components
export { default as Button } from './Button';
export { default as ActionButton } from './ActionButton';
export { default as AnimatedCheckbox } from './AnimatedCheckbox';
// Export types
export type { ButtonVariant, ButtonSize } from './Button';
export type { ActionType } from './ActionButton';