From d539796283c53007f5e23c9567814120775d097a Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 8 Aug 2025 12:20:28 +0200 Subject: [PATCH] CreateSessions aus characterlist ausgegliedert common functions un utils.js ausgelagert --- backend/database/config.go | 13 +- .../components/CharacterCreationSessions.vue | 108 +++++++++++++++ frontend/src/components/CharacterList.vue | 115 ++++------------ frontend/src/locales/de | 23 ++++ frontend/src/locales/en | 30 +++++ frontend/src/utils/dateUtils.d.ts | 35 +++++ frontend/src/utils/dateUtils.js | 123 ++++++++++++++++++ frontend/src/utils/utilsPlugin.js | 33 +++++ 8 files changed, 384 insertions(+), 96 deletions(-) create mode 100644 frontend/src/components/CharacterCreationSessions.vue create mode 100644 frontend/src/utils/dateUtils.d.ts create mode 100644 frontend/src/utils/dateUtils.js create mode 100644 frontend/src/utils/utilsPlugin.js diff --git a/backend/database/config.go b/backend/database/config.go index eb918f8..973479d 100644 --- a/backend/database/config.go +++ b/backend/database/config.go @@ -10,7 +10,6 @@ import ( "log" "gorm.io/driver/mysql" - "gorm.io/driver/sqlite" "gorm.io/gorm" ) @@ -39,11 +38,13 @@ var ( func ConnectDatabase() *gorm.DB { SetupTestDB() - db, err := gorm.Open(sqlite.Open(PreparedTestDB), &gorm.Config{}) - if err != nil { - log.Fatal("Failed to connect to database:", err) - } - DB = db + /* + db, err := gorm.Open(sqlite.Open(PreparedTestDB), &gorm.Config{}) + if err != nil { + log.Fatal("Failed to connect to database:", err) + } + DB = db + */ return DB } func ConnectDatabaseOrig() *gorm.DB { diff --git a/frontend/src/components/CharacterCreationSessions.vue b/frontend/src/components/CharacterCreationSessions.vue new file mode 100644 index 0000000..81b0062 --- /dev/null +++ b/frontend/src/components/CharacterCreationSessions.vue @@ -0,0 +1,108 @@ + + + + + diff --git a/frontend/src/components/CharacterList.vue b/frontend/src/components/CharacterList.vue index 42f1fd1..c2b5ed6 100644 --- a/frontend/src/components/CharacterList.vue +++ b/frontend/src/components/CharacterList.vue @@ -1,51 +1,24 @@ @@ -173,52 +152,8 @@ export default { font-size: 16px; } -.btn-small { - padding: 5px 10px; - font-size: 0.8rem; -} - -.sessions-section { - margin-bottom: 30px; -} - -.session-card { - cursor: pointer; -} - -.session-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 10px; -} - -.session-details { - margin-bottom: 10px; -} - -.session-meta { - display: flex; - flex-direction: column; - gap: 5px; - margin-bottom: 10px; - padding-top: 10px; - border-top: 1px solid #eee; -} - -.session-date { - font-size: 0.8rem; - color: #888; -} - /* Responsive Design */ @media (max-width: 768px) { - .session-header { - flex-direction: column; - align-items: flex-start; - gap: 5px; - } - .list-item { flex-direction: column; gap: 10px; diff --git a/frontend/src/locales/de b/frontend/src/locales/de index adadfe6..1ffffd0 100644 --- a/frontend/src/locales/de +++ b/frontend/src/locales/de @@ -176,6 +176,29 @@ export default { total_in_gs: 'Gesamt in GS' }, characters: { + list: { + title: 'Ihre Charaktere', + create_new: 'Neuen Charakter erstellen', + continue_creation: 'Charaktererstellung fortsetzen', + no_characters: 'Noch keine Charaktere', + no_characters_description: 'Erstellen Sie Ihren ersten Charakter um zu beginnen!', + view_details: 'Details anzeigen', + manage_equipment: 'Ausrüstung verwalten', + delete_draft: 'Entwurf löschen', + delete_draft_confirm: 'Sind Sie sicher, dass Sie diesen Charakterentwurf löschen möchten?', + race: 'Rasse', + class: 'Klasse', + current_step: 'Aktueller Schritt', + step: 'Schritt', + last_updated: 'Zuletzt aktualisiert', + expires: 'Läuft ab', + not_selected: 'Nicht ausgewählt', + unnamed_character: 'Unbenannter Charakter', + public: 'Öffentlich', + private: 'Privat', + grade: 'Grad', + owner: 'Besitzer' + }, create: { spells: { title: 'Zauber auswählen', diff --git a/frontend/src/locales/en b/frontend/src/locales/en index 6880334..bedfbb6 100644 --- a/frontend/src/locales/en +++ b/frontend/src/locales/en @@ -1,4 +1,11 @@ export default { + DatasheetView:'Datasheet', + SkillView: 'Skills', + WeaponView: 'Weapons', + SpellView: 'Spells', + EquipmentView: 'Equipment', + ExperianceView: 'Experience & Wealth', + DeleteCharView: 'Delete Character', char:'Char', stats: { strength: 'St', @@ -75,6 +82,29 @@ export default { total_in_gs: 'Total in GS' }, characters: { + list: { + title: 'Your Characters', + create_new: 'Create New Character', + continue_creation: 'Continue Character Creation', + no_characters: 'No Characters Yet', + no_characters_description: 'Create your first character to get started!', + view_details: 'View Details', + manage_equipment: 'Manage Equipment', + delete_draft: 'Delete Draft', + delete_draft_confirm: 'Are you sure you want to delete this character draft?', + race: 'Race', + class: 'Class', + current_step: 'Current step', + step: 'Step', + last_updated: 'Last updated', + expires: 'Expires', + not_selected: 'Not selected', + unnamed_character: 'Unnamed Character', + public: 'Public', + private: 'Private', + grade: 'Grade', + owner: 'Owner' + }, create: { spells: { title: 'Select Spells', diff --git a/frontend/src/utils/dateUtils.d.ts b/frontend/src/utils/dateUtils.d.ts new file mode 100644 index 0000000..86c46fd --- /dev/null +++ b/frontend/src/utils/dateUtils.d.ts @@ -0,0 +1,35 @@ +/** + * TypeScript Definitionen für Utility-Funktionen + */ + +export interface DateFormatOptions { + year?: 'numeric' | '2-digit' + month?: 'numeric' | '2-digit' | 'long' | 'short' | 'narrow' + day?: 'numeric' | '2-digit' + hour?: 'numeric' | '2-digit' + minute?: 'numeric' | '2-digit' + second?: 'numeric' | '2-digit' +} + +export declare function formatDate( + dateString: string | null | undefined, + locale?: string, + options?: DateFormatOptions +): string + +export declare function formatDateTime( + dateString: string | null | undefined, + locale?: string +): string + +export declare function formatRelativeDate( + dateString: string | null | undefined, + locale?: string +): string + +export declare function safeValue( + value: T | null | undefined, + fallback?: T +): T + +export declare function capitalize(str: string): string diff --git a/frontend/src/utils/dateUtils.js b/frontend/src/utils/dateUtils.js new file mode 100644 index 0000000..27233a8 --- /dev/null +++ b/frontend/src/utils/dateUtils.js @@ -0,0 +1,123 @@ +/** + * Gemeinsame Utility-Funktionen für die gesamte Anwendung + */ + +/** + * Formatiert ein Datum-String in ein lokales Datumsformat + * @param {string} dateString - ISO-Datum-String + * @param {string} locale - Sprach-/Ländercode (optional, default: browser locale) + * @param {Object} options - Intl.DateTimeFormat Optionen (optional) + * @returns {string} - Formatiertes Datum + */ +export function formatDate(dateString, locale = undefined, options = {}) { + if (!dateString) { + return 'Unknown' + } + + try { + const date = new Date(dateString) + + // Prüfe ob das Datum gültig ist + if (isNaN(date.getTime())) { + return 'Invalid Date' + } + + // Default-Optionen für Datumsformatierung + const defaultOptions = { + year: 'numeric', + month: '2-digit', + day: '2-digit', + ...options + } + + return date.toLocaleDateString(locale, defaultOptions) + } catch (error) { + console.warn('Error formatting date:', error) + return 'Invalid Date' + } +} + +/** + * Formatiert ein Datum-String mit Uhrzeit + * @param {string} dateString - ISO-Datum-String + * @param {string} locale - Sprach-/Ländercode (optional) + * @returns {string} - Formatiertes Datum mit Uhrzeit + */ +export function formatDateTime(dateString, locale = undefined) { + return formatDate(dateString, locale, { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit' + }) +} + +/** + * Formatiert ein Datum relativ (z.B. "vor 2 Stunden") + * @param {string} dateString - ISO-Datum-String + * @param {string} locale - Sprach-/Ländercode (optional) + * @returns {string} - Relatives Datum + */ +export function formatRelativeDate(dateString, locale = undefined) { + if (!dateString) { + return 'Unknown' + } + + try { + const date = new Date(dateString) + const now = new Date() + + if (isNaN(date.getTime())) { + return 'Invalid Date' + } + + // Für moderne Browser mit Intl.RelativeTimeFormat + if (typeof Intl !== 'undefined' && Intl.RelativeTimeFormat) { + const rtf = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' }) + const diffTime = date.getTime() - now.getTime() + const diffDays = Math.round(diffTime / (1000 * 60 * 60 * 24)) + + if (Math.abs(diffDays) < 1) { + const diffHours = Math.round(diffTime / (1000 * 60 * 60)) + if (Math.abs(diffHours) < 1) { + const diffMinutes = Math.round(diffTime / (1000 * 60)) + return rtf.format(diffMinutes, 'minute') + } + return rtf.format(diffHours, 'hour') + } + + return rtf.format(diffDays, 'day') + } + + // Fallback für ältere Browser + return formatDate(dateString, locale) + } catch (error) { + console.warn('Error formatting relative date:', error) + return formatDate(dateString, locale) + } +} + +/** + * Weitere gemeinsame Utility-Funktionen können hier hinzugefügt werden + */ + +/** + * Sicherheits-Check für leere Werte + * @param {*} value - Zu prüfender Wert + * @param {*} fallback - Fallback-Wert + * @returns {*} - Wert oder Fallback + */ +export function safeValue(value, fallback = '-') { + return value != null && value !== '' ? value : fallback +} + +/** + * Kapitalisiert den ersten Buchstaben eines Strings + * @param {string} str - Input String + * @returns {string} - String mit großem ersten Buchstaben + */ +export function capitalize(str) { + if (!str || typeof str !== 'string') return str + return str.charAt(0).toUpperCase() + str.slice(1) +} diff --git a/frontend/src/utils/utilsPlugin.js b/frontend/src/utils/utilsPlugin.js new file mode 100644 index 0000000..45d0754 --- /dev/null +++ b/frontend/src/utils/utilsPlugin.js @@ -0,0 +1,33 @@ +/** + * Vue Plugin für globale Utility-Funktionen + * + * Usage in main.js: + * import UtilsPlugin from './utils/utilsPlugin' + * app.use(UtilsPlugin) + * + * Usage in components: + * this.$formatDate(dateString) + * this.$safeValue(value, 'fallback') + */ + +import { formatDate, formatDateTime, formatRelativeDate, safeValue, capitalize } from './dateUtils' + +export default { + install(app) { + // Globale Properties für Vue 3 + app.config.globalProperties.$formatDate = formatDate + app.config.globalProperties.$formatDateTime = formatDateTime + app.config.globalProperties.$formatRelativeDate = formatRelativeDate + app.config.globalProperties.$safeValue = safeValue + app.config.globalProperties.$capitalize = capitalize + + // Provide/Inject für Composition API + app.provide('utils', { + formatDate, + formatDateTime, + formatRelativeDate, + safeValue, + capitalize + }) + } +}