Update package-lock.json and package.json to include 'globals' dependency and improve code formatting in various components for better readability.
Some checks failed
Code Analysis (JS/Vue) / analyze (push) Failing after 54s
Some checks failed
Code Analysis (JS/Vue) / analyze (push) Failing after 54s
This commit is contained in:
@@ -4,15 +4,35 @@
|
||||
<div class="fixed top-20 left-0 right-0 z-40 bg-white border-b border-gray-200 shadow-sm">
|
||||
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 py-3 sm:py-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<h1 class="text-xl sm:text-3xl font-display font-bold text-gray-900">Spielpläne bearbeiten</h1>
|
||||
<h1 class="text-xl sm:text-3xl font-display font-bold text-gray-900">
|
||||
Spielpläne bearbeiten
|
||||
</h1>
|
||||
<div class="space-x-3">
|
||||
<button @click="showUploadModal = true" class="inline-flex items-center px-3 py-1.5 sm:px-4 sm:py-2 rounded-lg bg-green-600 text-white hover:bg-green-700 text-sm sm:text-base">
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"></path>
|
||||
<button
|
||||
class="inline-flex items-center px-3 py-1.5 sm:px-4 sm:py-2 rounded-lg bg-green-600 text-white hover:bg-green-700 text-sm sm:text-base"
|
||||
@click="showUploadModal = true"
|
||||
>
|
||||
<svg
|
||||
class="w-4 h-4 mr-2"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
|
||||
/>
|
||||
</svg>
|
||||
CSV hochladen
|
||||
</button>
|
||||
<button @click="save" class="inline-flex items-center px-3 py-1.5 sm:px-4 sm:py-2 rounded-lg bg-primary-600 text-white hover:bg-primary-700 text-sm sm:text-base">Speichern</button>
|
||||
<button
|
||||
class="inline-flex items-center px-3 py-1.5 sm:px-4 sm:py-2 rounded-lg bg-primary-600 text-white hover:bg-primary-700 text-sm sm:text-base"
|
||||
@click="save"
|
||||
>
|
||||
Speichern
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -21,24 +41,45 @@
|
||||
<!-- Content with top padding -->
|
||||
<div class="pt-20 pb-16">
|
||||
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
|
||||
<!-- CSV Upload Section -->
|
||||
<div class="mb-8 bg-white rounded-xl shadow-lg p-6">
|
||||
<h2 class="text-xl font-semibold text-gray-900 mb-4">Vereins-Spielplan (CSV)</h2>
|
||||
<h2 class="text-xl font-semibold text-gray-900 mb-4">
|
||||
Vereins-Spielplan (CSV)
|
||||
</h2>
|
||||
|
||||
<!-- Current File Info -->
|
||||
<div v-if="currentFile" class="mb-4 p-4 bg-green-50 border border-green-200 rounded-lg">
|
||||
<div
|
||||
v-if="currentFile"
|
||||
class="mb-4 p-4 bg-green-50 border border-green-200 rounded-lg"
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center">
|
||||
<svg class="w-5 h-5 text-green-600 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
||||
<svg
|
||||
class="w-5 h-5 text-green-600 mr-2"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
<div>
|
||||
<p class="text-sm font-medium text-green-800">{{ currentFile.name }}</p>
|
||||
<p class="text-xs text-green-600">{{ currentFile.size }} bytes, {{ currentFile.lastModified ? new Date(currentFile.lastModified).toLocaleDateString('de-DE') : 'Unbekannt' }}</p>
|
||||
<p class="text-sm font-medium text-green-800">
|
||||
{{ currentFile.name }}
|
||||
</p>
|
||||
<p class="text-xs text-green-600">
|
||||
{{ currentFile.size }} bytes, {{ currentFile.lastModified ? new Date(currentFile.lastModified).toLocaleDateString('de-DE') : 'Unbekannt' }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<button @click="removeFile" class="px-3 py-1 text-sm bg-red-100 hover:bg-red-200 text-red-700 rounded-lg transition-colors">
|
||||
<button
|
||||
class="px-3 py-1 text-sm bg-red-100 hover:bg-red-200 text-red-700 rounded-lg transition-colors"
|
||||
@click="removeFile"
|
||||
>
|
||||
Entfernen
|
||||
</button>
|
||||
</div>
|
||||
@@ -46,46 +87,75 @@
|
||||
|
||||
<!-- Upload Area -->
|
||||
<div
|
||||
class="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center hover:border-primary-400 hover:bg-primary-50 transition-colors cursor-pointer"
|
||||
:class="{ 'border-primary-400 bg-primary-50': isDragOver }"
|
||||
@click="triggerFileInput"
|
||||
@dragover.prevent
|
||||
@dragenter.prevent
|
||||
@drop.prevent="handleFileDrop"
|
||||
class="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center hover:border-primary-400 hover:bg-primary-50 transition-colors cursor-pointer"
|
||||
:class="{ 'border-primary-400 bg-primary-50': isDragOver }"
|
||||
>
|
||||
<svg class="w-12 h-12 text-gray-400 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"></path>
|
||||
<svg
|
||||
class="w-12 h-12 text-gray-400 mx-auto mb-4"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
|
||||
/>
|
||||
</svg>
|
||||
<p class="text-lg font-medium text-gray-900 mb-2">CSV-Datei hochladen</p>
|
||||
<p class="text-sm text-gray-600 mb-4">Klicken Sie hier oder ziehen Sie eine CSV-Datei hierher</p>
|
||||
<p class="text-xs text-gray-500">Unterstützte Formate: .csv</p>
|
||||
<p class="text-lg font-medium text-gray-900 mb-2">
|
||||
CSV-Datei hochladen
|
||||
</p>
|
||||
<p class="text-sm text-gray-600 mb-4">
|
||||
Klicken Sie hier oder ziehen Sie eine CSV-Datei hierher
|
||||
</p>
|
||||
<p class="text-xs text-gray-500">
|
||||
Unterstützte Formate: .csv
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<input
|
||||
ref="fileInput"
|
||||
type="file"
|
||||
accept=".csv"
|
||||
@change="handleFileSelect"
|
||||
class="hidden"
|
||||
/>
|
||||
@change="handleFileSelect"
|
||||
>
|
||||
</div>
|
||||
|
||||
<!-- Column Selection -->
|
||||
<div v-if="csvData.length > 0 && !columnsSelected" class="bg-white rounded-xl shadow-lg p-6 mb-8">
|
||||
<h2 class="text-xl font-semibold text-gray-900 mb-4">Spalten auswählen</h2>
|
||||
<p class="text-sm text-gray-600 mb-6">Wählen Sie die Spalten aus, die für den Spielplan gespeichert werden sollen:</p>
|
||||
<div
|
||||
v-if="csvData.length > 0 && !columnsSelected"
|
||||
class="bg-white rounded-xl shadow-lg p-6 mb-8"
|
||||
>
|
||||
<h2 class="text-xl font-semibold text-gray-900 mb-4">
|
||||
Spalten auswählen
|
||||
</h2>
|
||||
<p class="text-sm text-gray-600 mb-6">
|
||||
Wählen Sie die Spalten aus, die für den Spielplan gespeichert werden sollen:
|
||||
</p>
|
||||
|
||||
<div class="space-y-4">
|
||||
<div v-for="(header, index) in csvHeaders" :key="index"
|
||||
class="flex items-center justify-between p-4 border border-gray-200 rounded-lg hover:bg-gray-50">
|
||||
<div
|
||||
v-for="(header, index) in csvHeaders"
|
||||
:key="index"
|
||||
class="flex items-center justify-between p-4 border border-gray-200 rounded-lg hover:bg-gray-50"
|
||||
>
|
||||
<div class="flex items-center">
|
||||
<input
|
||||
:id="`column-${index}`"
|
||||
v-model="selectedColumns[index]"
|
||||
type="checkbox"
|
||||
class="h-4 w-4 text-primary-600 focus:ring-primary-500 border-gray-300 rounded"
|
||||
/>
|
||||
<label :for="`column-${index}`" class="ml-3 text-sm font-medium text-gray-900">
|
||||
>
|
||||
<label
|
||||
:for="`column-${index}`"
|
||||
class="ml-3 text-sm font-medium text-gray-900"
|
||||
>
|
||||
{{ header }}
|
||||
</label>
|
||||
</div>
|
||||
@@ -100,18 +170,29 @@
|
||||
{{ selectedColumnsCount }} von {{ csvHeaders.length }} Spalten ausgewählt
|
||||
</div>
|
||||
<div class="space-x-3">
|
||||
<button @click="selectAllColumns" class="px-4 py-2 text-sm bg-gray-100 hover:bg-gray-200 text-gray-700 rounded-lg transition-colors">
|
||||
<button
|
||||
class="px-4 py-2 text-sm bg-gray-100 hover:bg-gray-200 text-gray-700 rounded-lg transition-colors"
|
||||
@click="selectAllColumns"
|
||||
>
|
||||
Alle auswählen
|
||||
</button>
|
||||
<button @click="deselectAllColumns" class="px-4 py-2 text-sm bg-gray-100 hover:bg-gray-200 text-gray-700 rounded-lg transition-colors">
|
||||
<button
|
||||
class="px-4 py-2 text-sm bg-gray-100 hover:bg-gray-200 text-gray-700 rounded-lg transition-colors"
|
||||
@click="deselectAllColumns"
|
||||
>
|
||||
Alle abwählen
|
||||
</button>
|
||||
<button @click="suggestHalleColumns" class="px-4 py-2 text-sm bg-blue-100 hover:bg-blue-200 text-blue-700 rounded-lg transition-colors">
|
||||
<button
|
||||
class="px-4 py-2 text-sm bg-blue-100 hover:bg-blue-200 text-blue-700 rounded-lg transition-colors"
|
||||
@click="suggestHalleColumns"
|
||||
>
|
||||
Halle-Spalten vorschlagen
|
||||
</button>
|
||||
<button @click="confirmColumnSelection"
|
||||
:disabled="selectedColumnsCount === 0"
|
||||
class="px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors disabled:bg-gray-400">
|
||||
<button
|
||||
:disabled="selectedColumnsCount === 0"
|
||||
class="px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors disabled:bg-gray-400"
|
||||
@click="confirmColumnSelection"
|
||||
>
|
||||
Auswahl bestätigen
|
||||
</button>
|
||||
</div>
|
||||
@@ -119,14 +200,25 @@
|
||||
</div>
|
||||
|
||||
<!-- Data Preview -->
|
||||
<div v-if="csvData.length > 0 && columnsSelected" class="bg-white rounded-xl shadow-lg p-6">
|
||||
<div
|
||||
v-if="csvData.length > 0 && columnsSelected"
|
||||
class="bg-white rounded-xl shadow-lg p-6"
|
||||
>
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2 class="text-xl font-semibold text-gray-900">Datenvorschau</h2>
|
||||
<h2 class="text-xl font-semibold text-gray-900">
|
||||
Datenvorschau
|
||||
</h2>
|
||||
<div class="flex space-x-2">
|
||||
<button @click="exportCSV" class="px-3 py-1 text-sm bg-blue-100 hover:bg-blue-200 text-blue-700 rounded-lg transition-colors">
|
||||
<button
|
||||
class="px-3 py-1 text-sm bg-blue-100 hover:bg-blue-200 text-blue-700 rounded-lg transition-colors"
|
||||
@click="exportCSV"
|
||||
>
|
||||
CSV exportieren
|
||||
</button>
|
||||
<button @click="clearData" class="px-3 py-1 text-sm bg-red-100 hover:bg-red-200 text-red-700 rounded-lg transition-colors">
|
||||
<button
|
||||
class="px-3 py-1 text-sm bg-red-100 hover:bg-red-200 text-red-700 rounded-lg transition-colors"
|
||||
@click="clearData"
|
||||
>
|
||||
Daten löschen
|
||||
</button>
|
||||
</div>
|
||||
@@ -137,17 +229,26 @@
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th v-for="(header, index) in (columnsSelected ? filteredCsvHeaders : csvHeaders)" :key="index"
|
||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
<th
|
||||
v-for="(header, index) in (columnsSelected ? filteredCsvHeaders : csvHeaders)"
|
||||
:key="index"
|
||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
|
||||
>
|
||||
{{ header }}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-200">
|
||||
<tr v-for="(row, rowIndex) in (columnsSelected ? filteredCsvData : csvData).slice(0, 10)" :key="rowIndex"
|
||||
:class="rowIndex % 2 === 0 ? 'bg-white' : 'bg-gray-50'">
|
||||
<td v-for="(cell, cellIndex) in row" :key="cellIndex"
|
||||
class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
|
||||
<tr
|
||||
v-for="(row, rowIndex) in (columnsSelected ? filteredCsvData : csvData).slice(0, 10)"
|
||||
:key="rowIndex"
|
||||
:class="rowIndex % 2 === 0 ? 'bg-white' : 'bg-gray-50'"
|
||||
>
|
||||
<td
|
||||
v-for="(cell, cellIndex) in row"
|
||||
:key="cellIndex"
|
||||
class="px-6 py-4 whitespace-nowrap text-sm text-gray-900"
|
||||
>
|
||||
{{ cell }}
|
||||
</td>
|
||||
</tr>
|
||||
@@ -155,7 +256,10 @@
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div v-if="(columnsSelected ? filteredCsvData : csvData).length > 10" class="mt-4 text-center text-sm text-gray-600">
|
||||
<div
|
||||
v-if="(columnsSelected ? filteredCsvData : csvData).length > 10"
|
||||
class="mt-4 text-center text-sm text-gray-600"
|
||||
>
|
||||
Zeige erste 10 von {{ (columnsSelected ? filteredCsvData : csvData).length }} Zeilen
|
||||
</div>
|
||||
|
||||
@@ -166,12 +270,29 @@
|
||||
</div>
|
||||
|
||||
<!-- Empty State -->
|
||||
<div v-else class="text-center py-12 bg-white rounded-xl shadow-lg">
|
||||
<svg class="w-12 h-12 text-gray-400 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
|
||||
<div
|
||||
v-else
|
||||
class="text-center py-12 bg-white rounded-xl shadow-lg"
|
||||
>
|
||||
<svg
|
||||
class="w-12 h-12 text-gray-400 mx-auto mb-4"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
|
||||
/>
|
||||
</svg>
|
||||
<p class="text-gray-600">Keine CSV-Daten geladen.</p>
|
||||
<p class="text-sm text-gray-500 mt-2">Laden Sie eine CSV-Datei hoch, um Spielplandaten zu verwalten.</p>
|
||||
<p class="text-gray-600">
|
||||
Keine CSV-Daten geladen.
|
||||
</p>
|
||||
<p class="text-sm text-gray-500 mt-2">
|
||||
Laden Sie eine CSV-Datei hoch, um Spielplandaten zu verwalten.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -183,7 +304,9 @@
|
||||
@click.self="closeUploadModal"
|
||||
>
|
||||
<div class="bg-white rounded-lg max-w-md w-full p-6">
|
||||
<h3 class="text-lg font-semibold text-gray-900 mb-4">CSV-Datei hochladen</h3>
|
||||
<h3 class="text-lg font-semibold text-gray-900 mb-4">
|
||||
CSV-Datei hochladen
|
||||
</h3>
|
||||
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
@@ -192,18 +315,27 @@
|
||||
ref="modalFileInput"
|
||||
type="file"
|
||||
accept=".csv"
|
||||
@change="handleModalFileSelect"
|
||||
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500"
|
||||
/>
|
||||
@change="handleModalFileSelect"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div v-if="selectedFile" class="p-3 bg-gray-50 rounded-lg">
|
||||
<p class="text-sm text-gray-700"><strong>Ausgewählte Datei:</strong> {{ selectedFile.name }}</p>
|
||||
<p class="text-xs text-gray-500">{{ selectedFile.size }} bytes</p>
|
||||
<div
|
||||
v-if="selectedFile"
|
||||
class="p-3 bg-gray-50 rounded-lg"
|
||||
>
|
||||
<p class="text-sm text-gray-700">
|
||||
<strong>Ausgewählte Datei:</strong> {{ selectedFile.name }}
|
||||
</p>
|
||||
<p class="text-xs text-gray-500">
|
||||
{{ selectedFile.size }} bytes
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-blue-50 p-4 rounded-lg">
|
||||
<h4 class="text-sm font-medium text-blue-800 mb-2">Erwartetes CSV-Format:</h4>
|
||||
<h4 class="text-sm font-medium text-blue-800 mb-2">
|
||||
Erwartetes CSV-Format:
|
||||
</h4>
|
||||
<div class="text-xs text-blue-700 space-y-1">
|
||||
<p>• Erste Zeile: Spaltenüberschriften</p>
|
||||
<p>• Spalten: Datum, Mannschaft, Gegner, Ort, Uhrzeit, etc.</p>
|
||||
@@ -215,15 +347,15 @@
|
||||
|
||||
<div class="flex justify-end space-x-3 pt-4">
|
||||
<button
|
||||
@click="closeUploadModal"
|
||||
class="px-4 py-2 text-gray-700 bg-gray-100 hover:bg-gray-200 rounded-lg transition-colors"
|
||||
@click="closeUploadModal"
|
||||
>
|
||||
Abbrechen
|
||||
</button>
|
||||
<button
|
||||
@click="processSelectedFile"
|
||||
:disabled="!selectedFile"
|
||||
class="px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors disabled:bg-gray-400"
|
||||
@click="processSelectedFile"
|
||||
>
|
||||
Hochladen
|
||||
</button>
|
||||
@@ -237,9 +369,13 @@
|
||||
class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4"
|
||||
>
|
||||
<div class="bg-white rounded-lg max-w-sm w-full p-6 text-center">
|
||||
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary-600 mx-auto mb-4"></div>
|
||||
<h3 class="text-lg font-semibold text-gray-900 mb-2">Verarbeitung läuft...</h3>
|
||||
<p class="text-sm text-gray-600">{{ processingMessage }}</p>
|
||||
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary-600 mx-auto mb-4" />
|
||||
<h3 class="text-lg font-semibold text-gray-900 mb-2">
|
||||
Verarbeitung läuft...
|
||||
</h3>
|
||||
<p class="text-sm text-gray-600">
|
||||
{{ processingMessage }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user