reworked scheduling

This commit is contained in:
2025-10-18 01:55:04 +02:00
parent b86040dc04
commit f705a83cd4
26 changed files with 3222 additions and 3193 deletions

View File

@@ -1,11 +1,9 @@
// frontend/src/design/DesignSystem.tsx
import React, { createContext, useContext, ReactNode } from 'react';
// Design Tokens
export const designTokens = {
colors: {
// Primary Colors
white: '#FBFAF6',
default_white: '#ddd', //boxes
white: '#FBFAF6', //background, fonts
black: '#161718',
// Purple Gradients
@@ -122,275 +120,4 @@ export const designTokens = {
xl: '1280px',
'2xl': '1536px',
},
} as const;
// Context for Design System
interface DesignSystemContextType {
tokens: typeof designTokens;
getColor: (path: string) => string;
getSpacing: (size: keyof typeof designTokens.spacing) => string;
}
const DesignSystemContext = createContext<DesignSystemContextType | undefined>(undefined);
// Design System Provider
interface DesignSystemProviderProps {
children: ReactNode;
}
export const DesignSystemProvider: React.FC<DesignSystemProviderProps> = ({ children }) => {
const getColor = (path: string): string => {
const parts = path.split('.');
let current: any = designTokens.colors;
for (const part of parts) {
if (current[part] === undefined) {
console.warn(`Color path "${path}" not found in design tokens`);
return designTokens.colors.primary;
}
current = current[part];
}
return current;
};
const getSpacing = (size: keyof typeof designTokens.spacing): string => {
return designTokens.spacing[size];
};
const value: DesignSystemContextType = {
tokens: designTokens,
getColor,
getSpacing,
};
return (
<DesignSystemContext.Provider value={value}>
{children}
</DesignSystemContext.Provider>
);
};
// Hook to use Design System
export const useDesignSystem = (): DesignSystemContextType => {
const context = useContext(DesignSystemContext);
if (context === undefined) {
throw new Error('useDesignSystem must be used within a DesignSystemProvider');
}
return context;
};
// Utility Components
export interface BoxProps {
children?: ReactNode;
className?: string;
style?: React.CSSProperties;
p?: keyof typeof designTokens.spacing;
px?: keyof typeof designTokens.spacing;
py?: keyof typeof designTokens.spacing;
m?: keyof typeof designTokens.spacing;
mx?: keyof typeof designTokens.spacing;
my?: keyof typeof designTokens.spacing;
bg?: string;
color?: string;
borderRadius?: keyof typeof designTokens.borderRadius;
}
export const Box: React.FC<BoxProps> = ({
children,
className,
style,
p,
px,
py,
m,
mx,
my,
bg,
color,
borderRadius,
...props
}) => {
const { tokens, getColor } = useDesignSystem();
const boxStyle: React.CSSProperties = {
padding: p && tokens.spacing[p],
paddingLeft: px && tokens.spacing[px],
paddingRight: px && tokens.spacing[px],
paddingTop: py && tokens.spacing[py],
paddingBottom: py && tokens.spacing[py],
margin: m && tokens.spacing[m],
marginLeft: mx && tokens.spacing[mx],
marginRight: mx && tokens.spacing[mx],
marginTop: my && tokens.spacing[my],
marginBottom: my && tokens.spacing[my],
backgroundColor: bg && getColor(bg),
color: color && getColor(color),
borderRadius: borderRadius && tokens.borderRadius[borderRadius],
fontFamily: tokens.typography.fontFamily,
...style,
};
return (
<div className={className} style={boxStyle} {...props}>
{children}
</div>
);
};
export interface TextProps {
children: ReactNode;
className?: string;
style?: React.CSSProperties;
variant?: 'xs' | 'sm' | 'base' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl';
weight?: keyof typeof designTokens.typography.fontWeights;
color?: string;
align?: 'left' | 'center' | 'right' | 'justify';
lineHeight?: keyof typeof designTokens.typography.lineHeights;
letterSpacing?: keyof typeof designTokens.typography.letterSpacing;
}
export const Text: React.FC<TextProps> = ({
children,
className,
style,
variant = 'base',
weight = 'normal',
color = 'text.primary',
align = 'left',
lineHeight = 'normal',
letterSpacing = 'normal',
...props
}) => {
const { tokens, getColor } = useDesignSystem();
const textStyle: React.CSSProperties = {
fontSize: tokens.typography.fontSizes[variant],
fontWeight: tokens.typography.fontWeights[weight],
color: getColor(color),
textAlign: align,
lineHeight: tokens.typography.lineHeights[lineHeight],
letterSpacing: tokens.typography.letterSpacing[letterSpacing],
fontFamily: tokens.typography.fontFamily,
...style,
};
return (
<span className={className} style={textStyle} {...props}>
{children}
</span>
);
};
// Global Styles Component
export const GlobalStyles: React.FC = () => {
const { tokens } = useDesignSystem();
const globalStyles = `
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
font-family: ${tokens.typography.fontFamily};
font-size: 16px;
line-height: ${tokens.typography.lineHeights.normal};
color: ${tokens.colors.text.primary};
background-color: ${tokens.colors.background};
}
body {
font-family: ${tokens.typography.fontFamily};
font-weight: ${tokens.typography.fontWeights.normal};
line-height: ${tokens.typography.lineHeights.normal};
color: ${tokens.colors.text.primary};
background-color: ${tokens.colors.background};
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
h1, h2, h3, h4, h5, h6 {
font-family: ${tokens.typography.fontFamily};
font-weight: ${tokens.typography.fontWeights.bold};
line-height: ${tokens.typography.lineHeights.tight};
color: ${tokens.colors.text.primary};
}
h1 {
font-size: ${tokens.typography.fontSizes['4xl']};
letter-spacing: ${tokens.typography.letterSpacing.tight};
}
h2 {
font-size: ${tokens.typography.fontSizes['3xl']};
letter-spacing: ${tokens.typography.letterSpacing.tight};
}
h3 {
font-size: ${tokens.typography.fontSizes['2xl']};
}
h4 {
font-size: ${tokens.typography.fontSizes.xl};
}
h5 {
font-size: ${tokens.typography.fontSizes.lg};
}
h6 {
font-size: ${tokens.typography.fontSizes.base};
}
p {
font-size: ${tokens.typography.fontSizes.base};
line-height: ${tokens.typography.lineHeights.relaxed};
color: ${tokens.colors.text.primary};
}
a {
color: ${tokens.colors.primary};
text-decoration: none;
transition: ${tokens.transitions.default};
}
a:hover {
color: ${tokens.colors.secondary};
}
button {
font-family: ${tokens.typography.fontFamily};
transition: ${tokens.transitions.default};
}
input, textarea, select {
font-family: ${tokens.typography.fontFamily};
}
/* Scrollbar Styling */
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: ${tokens.colors.background};
}
::-webkit-scrollbar-thumb {
background: ${tokens.colors.border.medium};
border-radius: ${tokens.borderRadius.full};
}
::-webkit-scrollbar-thumb:hover {
background: ${tokens.colors.border.dark};
}
`;
return <style>{globalStyles}</style>;
};
export default designTokens;
} as const;

View File

@@ -1,4 +0,0 @@
// frontend/src/design/index.ts
export { designTokens } from './DesignSystem';
export { DesignSystemProvider, useDesignSystem, GlobalStyles, Box, Text } from './DesignSystem';
export type { BoxProps, TextProps } from './DesignSystem';