diff --git a/.drone.yml.back b/.drone.yml.back
deleted file mode 100644
index a41ab47..0000000
--- a/.drone.yml.back
+++ /dev/null
@@ -1,152 +0,0 @@
-kind: pipeline
-type: docker
-name: default
-trigger:
- branch:
- - master
-
-steps:
-- name: debug-secrets
- image: alpine
- environment:
- VAULT_API_URL:
- from_secret: VAULT_API_URL
- commands:
- - 'echo "Docker Registry URL: $${VAULT_API_URL}"'
- when:
- event:
- - push
- - tag
-
-# Make the image available for next step
-- name: publish
- image: plugins/docker
- settings:
- build_args:
- - NEXT_PUBLIC_PYTHON_API_URL=https://api.playchoo.com
- - NEXT_PUBLIC_AUTH_BACKEND_URL=https://auth.api.playchoo.com
- - NEXT_PUBLIC_SWISSOID_TARGET_SERVICE_HANDLE=playchoo
- - NEXT_PUBLIC_APP_VERSION=1.0.10
- dockerfile: docker/Dockerfile
- context: .
- registry: registry.sn48.zivili.ch
- repo: registry.sn48.zivili.ch/meow/playchoo-nextjs
- tags:
- - "amd64-1.0.0"
- - "latest"
- username:
- from_secret: PORTUS_USER
- password:
- from_secret: PORTUS_PASSWORD
- debug: true
- launch_debug: true
- # make sure to replace image with same tag
- force_tag: true
- when:
- event:
- - push
- - tag
-
-- name: deploy
- image: registry.sn48.zivili.ch/meow/drone-deploy:amd64-1.0.0
- pull: never
- settings:
- ssh_port:
- from_secret: SSH_PORT
- # this is required for the moment to generate the .docker/config.json
- # drone is failing to do it on its own at the moment
- dockerconfigjson:
- from_secret: dockerconfigjson
- # use portus or directly docker logins
- portus_user:
- from_secret: PORTUS_USER
- portus_password:
- from_secret: PORTUS_PASSWORD
- # used by deploy to login to deploy server
- ssh_host:
- from_secret: SSH_HOST
- ssh_user:
- from_secret: SSH_USER
- ssh_key:
- from_secret: SSH_KEY
- ssh_fingerprint:
- from_secret: SSH_FINGERPRINT
- # used by the deploy script to gather all project's .env values from vault
- drone_agent1_token:
- from_secret: DRONE_AGENT1_TOKEN
- # used by deploy script to know where to gather secrets from
- vault_api_url:
- from_secret: VAULT_API_URL
-
----
-kind: secret
-name: SSH_HOST
-get:
- path: kv/data/__drone-admin-secrets
- name: SSH_HOST
-
----
-kind: secret
-name: SSH_USER
-get:
- path: kv/data/__drone-admin-secrets
- name: SSH_USER
-
----
-kind: secret
-name: SSH_KEY
-get:
- path: kv/data/__drone-admin-secrets
- name: SSH_KEY
-
----
-kind: secret
-name: DRONE_AGENT1_TOKEN
-get:
- path: kv/data/__drone-admin-secrets
- name: DRONE_AGENT1_TOKEN
-
----
-kind: secret
-name: VAULT_API_URL
-get:
- path: kv/data/__drone-admin-secrets
- name: VAULT_API_URL
-
----
-kind: secret
-name: PORTUS_USER
-get:
- path: kv/data/__drone-admin-secrets
- name: PORTUS_USER
-
----
-kind: secret
-name: PORTUS_PASSWORD
-get:
- path: kv/data/__drone-admin-secrets
- name: PORTUS_PASSWORD
-
----
-kind: secret
-name: dockerconfigjson
-get:
- path: kv/data/__drone-admin-secrets
- name: dockerconfigjson
-
-image_pull_secrets:
- from_secret: dockerconfigjson
-
----
-kind: secret
-name: SSH_PORT
-get:
- path: kv/data/__drone-admin-secrets
- name: SSH_PORT
-
----
-kind: secret
-name: SSH_FINGERPRINT
-get:
- path: kv/data/__drone-admin-secrets
- name: SSH_FINGERPRINT
diff --git a/src/app/[locale]/admin/clubs/[club_id]/tabs/ClubCourtsTab.tsx b/src/app/[locale]/admin/clubs/[club_id]/tabs/ClubCourtsTab.tsx
index d4e3928..b35f8d7 100644
--- a/src/app/[locale]/admin/clubs/[club_id]/tabs/ClubCourtsTab.tsx
+++ b/src/app/[locale]/admin/clubs/[club_id]/tabs/ClubCourtsTab.tsx
@@ -276,7 +276,7 @@ function CourtFormModal({ clubId, court, onClose, onSuccess }: CourtFormModalPro
if (nameError) {
setFieldError(nameError.message);
}
- } else if (result.error.code === 'duplicate_court_name') {
+ } else if (result.error.code === 'court_name_duplicate') {
setFieldError(result.error.detail);
} else {
setError(result.error.detail);
@@ -496,11 +496,19 @@ function DependenciesBlockingModal({ court, dependencies, onClose }: Dependencie
)}
- {dependencies.dependencies.upcoming_bookings > 0 && (
+ {dependencies.dependencies.slot_instances_future > 0 && (
- Upcoming bookings:
+ Future slot instances:
- {dependencies.dependencies.upcoming_bookings}
+ {dependencies.dependencies.slot_instances_future}
+
+
+ )}
+ {dependencies.dependencies.slot_instances_booked > 0 && (
+
+ Booked slot instances:
+
+ {dependencies.dependencies.slot_instances_booked}
)}
@@ -514,8 +522,11 @@ function DependenciesBlockingModal({ court, dependencies, onClose }: Dependencie
{dependencies.dependencies.slot_definitions > 0 && (
Delete or reassign all slot definitions
)}
- {dependencies.dependencies.upcoming_bookings > 0 && (
- Cancel or move all upcoming bookings
+ {dependencies.dependencies.slot_instances_future > 0 && (
+ Delete future slot instances
+ )}
+ {dependencies.dependencies.slot_instances_booked > 0 && (
+ Cancel or move all booked slot instances
)}
diff --git a/src/app/[locale]/admin/clubs/[club_id]/tabs/ClubProfileTab.tsx b/src/app/[locale]/admin/clubs/[club_id]/tabs/ClubProfileTab.tsx
index c5b898c..8be2c58 100644
--- a/src/app/[locale]/admin/clubs/[club_id]/tabs/ClubProfileTab.tsx
+++ b/src/app/[locale]/admin/clubs/[club_id]/tabs/ClubProfileTab.tsx
@@ -1,7 +1,7 @@
'use client';
import { useState, useEffect } from 'react';
-import { Loader2, AlertCircle, CheckCircle } from 'lucide-react';
+import { Loader2, AlertCircle, CheckCircle, Info } from 'lucide-react';
import { getClubProfile, updateClubProfile } from '@/src/lib/api/courts';
import type { ClubProfile, ClubProfileUpdateRequest} from '@/src/types/courts';
import { COMMON_TIMEZONES, isValidEmail, isValidUrl } from '@/src/types/courts';
@@ -43,17 +43,17 @@ export default function ClubProfileTab({ clubId, onUpdate }: ClubProfileTabProps
const prof = result.data;
setProfile(prof);
- // Populate form
+ // Populate form - read from settings structure
setName(prof.name);
setTimezone(prof.timezone);
- setAddressLine1(prof.address_line_1 || '');
- setAddressLine2(prof.address_line_2 || '');
- setCity(prof.city || '');
- setPostalCode(prof.postal_code || '');
- setCountry(prof.country || '');
- setPhone(prof.phone || '');
- setEmail(prof.email || '');
- setWebsite(prof.website || '');
+ setAddressLine1(prof.settings?.address?.line_1 || '');
+ setAddressLine2(prof.settings?.address?.line_2 || '');
+ setCity(prof.settings?.address?.city || '');
+ setPostalCode(prof.settings?.address?.postal_code || '');
+ setCountry(prof.settings?.address?.country || '');
+ setPhone(prof.settings?.contact?.phone || '');
+ setEmail(prof.settings?.contact?.email || '');
+ setWebsite(prof.settings?.contact?.website || '');
setError(null);
} else {
@@ -97,17 +97,29 @@ export default function ClubProfileTab({ clubId, onUpdate }: ClubProfileTabProps
setError(null);
setSuccess(false);
+ // Build settings structure, preserving existing settings
+ const updatedSettings = {
+ ...profile?.settings,
+ address: {
+ ...profile?.settings?.address,
+ line_1: addressLine1.trim() || undefined,
+ line_2: addressLine2.trim() || undefined,
+ city: city.trim() || undefined,
+ postal_code: postalCode.trim() || undefined,
+ country: country.trim() || undefined,
+ },
+ contact: {
+ ...profile?.settings?.contact,
+ phone: phone.trim() || undefined,
+ email: email.trim() || undefined,
+ website: website.trim() || undefined,
+ },
+ };
+
const request: ClubProfileUpdateRequest = {
name: name.trim(),
timezone,
- address_line_1: addressLine1.trim() || undefined,
- address_line_2: addressLine2.trim() || undefined,
- city: city.trim() || undefined,
- postal_code: postalCode.trim() || undefined,
- country: country.trim() || undefined,
- phone: phone.trim() || undefined,
- email: email.trim() || undefined,
- website: website.trim() || undefined,
+ settings: updatedSettings,
};
const result = await updateClubProfile(clubId, request);
@@ -143,17 +155,17 @@ export default function ClubProfileTab({ clubId, onUpdate }: ClubProfileTabProps
function handleCancel() {
if (!profile) return;
- // Reset form to original values
+ // Reset form to original values - read from settings structure
setName(profile.name);
setTimezone(profile.timezone);
- setAddressLine1(profile.address_line_1 || '');
- setAddressLine2(profile.address_line_2 || '');
- setCity(profile.city || '');
- setPostalCode(profile.postal_code || '');
- setCountry(profile.country || '');
- setPhone(profile.phone || '');
- setEmail(profile.email || '');
- setWebsite(profile.website || '');
+ setAddressLine1(profile.settings?.address?.line_1 || '');
+ setAddressLine2(profile.settings?.address?.line_2 || '');
+ setCity(profile.settings?.address?.city || '');
+ setPostalCode(profile.settings?.address?.postal_code || '');
+ setCountry(profile.settings?.address?.country || '');
+ setPhone(profile.settings?.contact?.phone || '');
+ setEmail(profile.settings?.contact?.email || '');
+ setWebsite(profile.settings?.contact?.website || '');
setErrors({});
setError(null);
}
@@ -260,7 +272,15 @@ export default function ClubProfileTab({ clubId, onUpdate }: ClubProfileTabProps
{/* Location */}
- Location
+
+
Location
+
+
+
+ Stored in settings until native fields ship
+
+
+
{/* Address Line 1 */}
@@ -348,7 +368,15 @@ export default function ClubProfileTab({ clubId, onUpdate }: ClubProfileTabProps
{/* Contact */}
- Contact
+
+
Contact
+
+
+
+ Stored in settings until native fields ship
+
+
+
{/* Phone */}
@@ -415,24 +443,6 @@ export default function ClubProfileTab({ clubId, onUpdate }: ClubProfileTabProps
- {/* Integration (read-only) */}
-
- Integration
-
-
-
- Provider:
- {profile.provider}
-
- {profile.provider !== 'local' && profile.remote_club_id && (
-
- Remote Club ID:
- {profile.remote_club_id}
-
- )}
-
-
-
{/* Actions */}