feat: Generate random vibrant skill color by default on every new skill creation while retaining custom color picker

This commit is contained in:
Richard
2026-07-31 10:48:24 +02:00
parent bc9d7caa73
commit 67b02f6646
6 changed files with 75 additions and 60 deletions
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -11,7 +11,7 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700&family=JetBrains+Mono:wght@400;500;600;700&family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700&family=JetBrains+Mono:wght@400;500;600;700&family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<title>Schichtplaner — Veranstaltungsschichtpläne</title> <title>Schichtplaner — Veranstaltungsschichtpläne</title>
<script type="module" crossorigin src="/assets/index--P5dGUAY.js"></script> <script type="module" crossorigin src="/assets/index-9dCYFrQm.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DyS9UMYS.css"> <link rel="stylesheet" crossorigin href="/assets/index-DyS9UMYS.css">
</head> </head>
<body class="bg-paper text-main font-sans antialiased min-h-screen"> <body class="bg-paper text-main font-sans antialiased min-h-screen">
+3 -1
View File
@@ -1,6 +1,7 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { X, User, Award, Check, AlertCircle } from 'lucide-react'; import { X, User, Award, Check, AlertCircle } from 'lucide-react';
import { apiFetch } from '../api/client'; import { apiFetch } from '../api/client';
import { getRandomSkillColor } from '../utils/colors';
export default function ProfileModal({ user, skills, onClose, onUserUpdated, onRefreshSkills }) { export default function ProfileModal({ user, skills, onClose, onUserUpdated, onRefreshSkills }) {
const [displayName, setDisplayName] = useState(user?.display_name || ''); const [displayName, setDisplayName] = useState(user?.display_name || '');
@@ -11,7 +12,7 @@ export default function ProfileModal({ user, skills, onClose, onUserUpdated, onR
// New skill fields // New skill fields
const [newSkillName, setNewSkillName] = useState(''); const [newSkillName, setNewSkillName] = useState('');
const [newSkillDesc, setNewSkillDesc] = useState(''); const [newSkillDesc, setNewSkillDesc] = useState('');
const [newSkillColor, setNewSkillColor] = useState('#2563eb'); const [newSkillColor, setNewSkillColor] = useState(getRandomSkillColor());
const [savingProfile, setSavingProfile] = useState(false); const [savingProfile, setSavingProfile] = useState(false);
const [creatingSkill, setCreatingSkill] = useState(false); const [creatingSkill, setCreatingSkill] = useState(false);
@@ -67,6 +68,7 @@ export default function ProfileModal({ user, skills, onClose, onUserUpdated, onR
}); });
setNewSkillName(''); setNewSkillName('');
setNewSkillDesc(''); setNewSkillDesc('');
setNewSkillColor(getRandomSkillColor());
setSuccess('Neue Fähigkeit erfolgreich angelegt!'); setSuccess('Neue Fähigkeit erfolgreich angelegt!');
onRefreshSkills(); onRefreshSkills();
} catch (err) { } catch (err) {
+3 -1
View File
@@ -1,11 +1,12 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { X, Award, Plus, Check, AlertCircle } from 'lucide-react'; import { X, Award, Plus, Check, AlertCircle } from 'lucide-react';
import { apiFetch } from '../api/client'; import { apiFetch } from '../api/client';
import { getRandomSkillColor } from '../utils/colors';
export default function SkillsModal({ skills, user, onClose, onRefreshSkills, onRefreshUser }) { export default function SkillsModal({ skills, user, onClose, onRefreshSkills, onRefreshUser }) {
const [newSkillName, setNewSkillName] = useState(''); const [newSkillName, setNewSkillName] = useState('');
const [newSkillDesc, setNewSkillDesc] = useState(''); const [newSkillDesc, setNewSkillDesc] = useState('');
const [newSkillColor, setNewSkillColor] = useState('#3b82f6'); const [newSkillColor, setNewSkillColor] = useState(getRandomSkillColor());
const [creating, setCreating] = useState(false); const [creating, setCreating] = useState(false);
const [savingUserSkills, setSavingUserSkills] = useState(false); const [savingUserSkills, setSavingUserSkills] = useState(false);
@@ -39,6 +40,7 @@ export default function SkillsModal({ skills, user, onClose, onRefreshSkills, on
}); });
setNewSkillName(''); setNewSkillName('');
setNewSkillDesc(''); setNewSkillDesc('');
setNewSkillColor(getRandomSkillColor());
setSuccess('Fähigkeit erfolgreich angelegt!'); setSuccess('Fähigkeit erfolgreich angelegt!');
onRefreshSkills(); onRefreshSkills();
} catch (err) { } catch (err) {
+3 -1
View File
@@ -7,6 +7,7 @@ import {
Mail, Send, Lock Mail, Send, Lock
} from 'lucide-react'; } from 'lucide-react';
import { apiFetch } from '../api/client'; import { apiFetch } from '../api/client';
import { getRandomSkillColor } from '../utils/colors';
export default function AdminPage({ branding, onRefreshBranding, onRefreshEvents, skills, onRefreshSkills }) { export default function AdminPage({ branding, onRefreshBranding, onRefreshEvents, skills, onRefreshSkills }) {
const [activeAdminTab, setActiveAdminTab] = useState('users'); // 'users' | 'events' | 'templates' | 'branding' | 'smtp' const [activeAdminTab, setActiveAdminTab] = useState('users'); // 'users' | 'events' | 'templates' | 'branding' | 'smtp'
@@ -32,7 +33,7 @@ export default function AdminPage({ branding, onRefreshBranding, onRefreshEvents
const [templatesList, setTemplatesList] = useState([]); const [templatesList, setTemplatesList] = useState([]);
const [newSkillName, setNewSkillName] = useState(''); const [newSkillName, setNewSkillName] = useState('');
const [newSkillDesc, setNewSkillDesc] = useState(''); const [newSkillDesc, setNewSkillDesc] = useState('');
const [newSkillColor, setNewSkillColor] = useState('#E05A47'); const [newSkillColor, setNewSkillColor] = useState(getRandomSkillColor());
// 4. Branding & Layout State // 4. Branding & Layout State
const [appName, setAppName] = useState(branding?.app_name || 'Veranstaltungsschichtplaner'); const [appName, setAppName] = useState(branding?.app_name || 'Veranstaltungsschichtplaner');
@@ -238,6 +239,7 @@ export default function AdminPage({ branding, onRefreshBranding, onRefreshEvents
}); });
setNewSkillName(''); setNewSkillName('');
setNewSkillDesc(''); setNewSkillDesc('');
setNewSkillColor(getRandomSkillColor());
onRefreshSkills(); onRefreshSkills();
showNotif('Qualifikation angelegt.'); showNotif('Qualifikation angelegt.');
} catch (e) { } catch (e) {
+9
View File
@@ -0,0 +1,9 @@
export const VIBRANT_SKILL_COLORS = [
'#E05A47', '#3B82F6', '#10B981', '#8B5CF6', '#F59E0B',
'#EC4899', '#06B6D4', '#6366F1', '#14B8A6', '#F97316',
'#D97706', '#059669', '#7C3AED', '#DB2777', '#2563EB'
];
export const getRandomSkillColor = () => {
return VIBRANT_SKILL_COLORS[Math.floor(Math.random() * VIBRANT_SKILL_COLORS.length)];
};