settings.html 811 lignes · 51704 octets
{% extends "base.html" %}

{% block title %}{{ page_title }}{% endblock %}

{% block navbar %}
{% include "components/navbar.html" %}
{% endblock %}

{% block content %}
<div class="container mx-auto px-4 py-8">
    <!-- Breadcrumb -->
    <div class="text-sm breadcrumbs mb-6">
        <ul>
            <li><a href="/">{{ breadcrumb_home }}</a></li>
            <li><a href="/admin">{{ breadcrumb_admin }}</a></li>
            <li>{{ breadcrumb_settings }}</li>
        </ul>
    </div>

    <!-- Page Header -->
    <div class="mb-8">
        <h1 class="text-3xl font-bold mb-2">⚙️ {{ title }}</h1>
        <p class="text-base-content/70">{{ subtitle }}</p>
    </div>

    <form id="settingsForm" method="POST" action="/admin/settings" class="space-y-6 max-w-6xl">
        <input type="hidden" name="csrf_token" value="{{ csrf_token }}">

        <!-- General Settings Card -->
        <div class="card bg-base-100 shadow-xl">
            <div class="card-body">
                <h2 class="card-title text-xl mb-4">
                    <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9" /></svg>
                    {{ general }}
                </h2>
                
                <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                    <!-- App Name -->
                    <div class="form-control">
                        <label class="label">
                            <span class="label-text font-semibold">{{ app_name_label }}</span>
                        </label>
                        <input 
                            type="text" 
                            name="app_name" 
                            value="{{ settings.app_name }}" 
                            class="input input-bordered w-full"
                        >
                    </div>

                    <!-- App Domain -->
                    <div class="form-control">
                        <label class="label">
                            <span class="label-text font-semibold">{{ app_domain_label }}</span>
                        </label>
                        <input 
                            type="text" 
                            name="app_domain" 
                            value="{{ settings.app_domain }}" 
                            class="input input-bordered w-full"
                            placeholder="{{ app_domain_placeholder }}"
                        >
                    </div>

                    <!-- App Description -->
                    <div class="form-control md:col-span-2">
                        <label class="label">
                            <span class="label-text font-semibold">{{ app_description_label }}</span>
                        </label>
                        <textarea 
                            name="app_description" 
                            class="textarea textarea-bordered w-full"
                            rows="2"
                        >{{ settings.app_description }}</textarea>
                    </div>

                    <!-- Allow Registration -->
                    <div class="form-control">
                        <label class="label cursor-pointer justify-start gap-4">
                            <input 
                                type="checkbox" 
                                name="allow_registration" 
                                value="true"
                                class="checkbox checkbox-primary"
                                {% if settings.allow_registration == "true" %}checked{% endif %}
                            >
                            <div>
                                <span class="label-text font-semibold">{{ allow_registration_label }}</span>
                                <span class="label-text-alt block">{{ allow_registration_desc }}</span>
                            </div>
                        </label>
                    </div>

                    <!-- Validation email requise -->
                    <div class="form-control">
                        <label class="label cursor-pointer justify-start gap-4">
                            <input 
                                type="checkbox" 
                                name="validation_email_requise" 
                                value="true"
                                class="checkbox checkbox-primary"
                                {% if settings.validation_email_requise == "true" %}checked{% endif %}
                            >
                            <div>
                                <span class="label-text font-semibold">{{ email_validation_required_label }}</span>
                                <span class="label-text-alt block">{{ email_validation_required_desc }}</span>
                            </div>
                        </label>
                    </div>
                </div>
            </div>
        </div>

        <!-- Password Security Card -->
        <div class="card bg-base-100 shadow-xl">
            <div class="card-body">
                <h2 class="card-title text-xl mb-4">
                    <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" /></svg>
                    {{ password_security }}
                </h2>

                <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                    <!-- Min Length -->
                    <div class="form-control">
                        <label class="label">
                            <span class="label-text font-semibold">{{ password_min_length }}</span>
                        </label>
                        <input 
                            type="number" 
                            name="password_min_length" 
                            value="{{ settings.password_min_length }}" 
                            class="input input-bordered w-full"
                            min="6"
                            max="128"
                        >
                        <label class="label">
                            <span class="label-text-alt">{{ password_min_length_hint }}</span>
                        </label>
                    </div>

                    <!-- Complexity Requirements -->
                    <div class="space-y-2">
                        <label class="label">
                            <span class="label-text font-semibold">{{ password_complexity }}</span>
                        </label>
                        <div class="form-control">
                            <label class="label cursor-pointer justify-start gap-3 py-1">
                                <input 
                                    type="checkbox" 
                                    name="password_require_uppercase" 
                                    value="true"
                                    class="checkbox checkbox-sm"
                                    {% if settings.password_require_uppercase == "true" %}checked{% endif %}
                                >
                                <span class="label-text">{{ require_uppercase }}</span>
                            </label>
                        </div>
                        <div class="form-control">
                            <label class="label cursor-pointer justify-start gap-3 py-1">
                                <input 
                                    type="checkbox" 
                                    name="password_require_lowercase" 
                                    value="true"
                                    class="checkbox checkbox-sm"
                                    {% if settings.password_require_lowercase == "true" %}checked{% endif %}
                                >
                                <span class="label-text">{{ require_lowercase }}</span>
                            </label>
                        </div>
                        <div class="form-control">
                            <label class="label cursor-pointer justify-start gap-3 py-1">
                                <input 
                                    type="checkbox" 
                                    name="password_require_digits" 
                                    value="true"
                                    class="checkbox checkbox-sm"
                                    {% if settings.password_require_digits == "true" %}checked{% endif %}
                                >
                                <span class="label-text">{{ require_digits }}</span>
                            </label>
                        </div>
                        <div class="form-control">
                            <label class="label cursor-pointer justify-start gap-3 py-1">
                                <input 
                                    type="checkbox" 
                                    name="password_require_special" 
                                    value="true"
                                    class="checkbox checkbox-sm"
                                    {% if settings.password_require_special == "true" %}checked{% endif %}
                                >
                                <span class="label-text">{{ require_special }}</span>
                            </label>
                        </div>
                    </div>

                    <!-- Password change email confirmation -->
                    <div class="form-control mt-4">
                        <label class="label cursor-pointer justify-start gap-4">
                            <input
                                type="checkbox"
                                name="password_change_require_email"
                                value="true"
                                class="toggle toggle-primary"
                                {% if settings.password_change_require_email == "true" %}checked{% endif %}
                            >
                            <div>
                                <span class="label-text font-medium">{{ password_change_require_email }}</span>
                                <p class="text-xs text-base-content/60 mt-0.5">{{ password_change_require_email_desc }}</p>
                            </div>
                        </label>
                    </div>

                    <!-- Password Expiration -->
                    <div class="form-control">
                        <label class="label cursor-pointer justify-start gap-4">
                            <input
                                type="checkbox"
                                name="password_expiration_enabled"
                                value="true"
                                class="checkbox checkbox-primary"
                                id="expirationEnabled"
                                {% if settings.password_expiration_enabled == "true" %}checked{% endif %}
                            >
                            <div>
                                <span class="label-text font-semibold">{{ password_expiration }}</span>
                                <span class="label-text-alt block">{{ password_expiration_desc }}</span>
                            </div>
                        </label>
                    </div>

                    <div id="expirationSettings" class="space-y-3">
                        <div class="form-control">
                            <label class="label">
                                <span class="label-text">{{ expiration_days }}</span>
                            </label>
                            <input 
                                type="number" 
                                name="password_expiration_days" 
                                value="{{ settings.password_expiration_days }}" 
                                class="input input-bordered input-sm w-full"
                                min="0"
                                max="365"
                            >
                        </div>

                        <div class="form-control">
                            <label class="label cursor-pointer justify-start gap-3">
                                <input 
                                    type="checkbox" 
                                    name="password_expiration_alert_enabled" 
                                    value="true"
                                    class="checkbox checkbox-sm"
                                    {% if settings.password_expiration_alert_enabled == "true" %}checked{% endif %}
                                >
                                <span class="label-text">{{ expiration_alert }}</span>
                            </label>
                        </div>

                        <div class="form-control">
                            <label class="label">
                                <span class="label-text">{{ expiration_alert_days }}</span>
                            </label>
                            <input 
                                type="number" 
                                name="password_expiration_alert_days" 
                                value="{{ settings.password_expiration_alert_days_before }}" 
                                class="input input-bordered input-sm w-full"
                                min="0"
                                max="30"
                            >
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- Two-Factor Authentication Card -->
        <div class="card bg-base-100 shadow-xl">
            <div class="card-body">
                <h2 class="card-title text-xl mb-4">
                    <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" /></svg>
                    Authentification à deux facteurs
                </h2>

                <div class="form-control">
                    <label class="label cursor-pointer justify-start gap-4">
                        <input
                            type="checkbox"
                            name="totp_force_enabled"
                            value="true"
                            class="toggle toggle-primary"
                            {% if settings.totp_force_enabled == "true" %}checked{% endif %}
                        />
                        <div>
                            <span class="label-text font-semibold">Forcer le 2FA pour tous les utilisateurs</span>
                            <p class="text-xs text-base-content/60 mt-1">Lorsqu'activé, tous les utilisateurs devront configurer l'authentification à deux facteurs avant de pouvoir accéder à l'application.</p>
                        </div>
                    </label>
                </div>
            </div>
        </div>

        <!-- Audit Logging Card -->
        <div class="card bg-base-100 shadow-xl">
            <div class="card-body">
                <h2 class="card-title text-xl mb-4">
                    <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><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>
                    {{ audit_logging }}
                </h2>

                <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                    <!-- Log Level -->
                    <div class="form-control">
                        <label class="label">
                            <span class="label-text font-semibold">{{ log_level }}</span>
                        </label>
                        <select 
                            name="audit_log_level" 
                            class="select select-bordered w-full"
                        >
                            <option value="DEBUG" {% if settings.audit_log_level == "DEBUG" %}selected{% endif %}>{{ log_level_debug }}</option>
                            <option value="INFO" {% if settings.audit_log_level == "INFO" %}selected{% endif %}>{{ log_level_info }}</option>
                            <option value="WARN" {% if settings.audit_log_level == "WARN" %}selected{% endif %}>{{ log_level_warn }}</option>
                            <option value="ERROR" {% if settings.audit_log_level == "ERROR" %}selected{% endif %}>{{ log_level_error }}</option>
                        </select>
                        <label class="label">
                            <span class="label-text-alt">{{ log_level_hint }}</span>
                        </label>
                    </div>

                    <!-- Retention -->
                    <div class="form-control">
                        <label class="label">
                            <span class="label-text font-semibold">{{ log_retention }}</span>
                        </label>
                        <input 
                            type="number" 
                            name="audit_log_retention_days" 
                            value="{{ settings.audit_log_retention_days }}" 
                            class="input input-bordered w-full"
                            min="1"
                            max="365"
                        >
                        <label class="label">
                            <span class="label-text-alt">{{ log_retention_hint }}</span>
                        </label>
                    </div>
                </div>

                <div class="alert alert-info mt-4">
                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="stroke-current shrink-0 w-6 h-6"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
                    <span class="text-sm">{{ audit_info_message }}</span>
                </div>
            </div>
        </div>

        <!-- OAuth / SSO Card -->
        <div class="card bg-base-100 shadow-xl">
            <div class="card-body">
                <h2 class="card-title text-xl mb-4">
                    <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z" /></svg>
                    {{ oauth_sso_title }}
                </h2>

                <div class="space-y-4">
                    <!-- Global OAuth Toggle -->
                    <div class="form-control">
                        <label class="label cursor-pointer justify-start gap-4">
                            <input type="checkbox" name="oauth_enabled" value="true" class="toggle toggle-primary" id="oauthEnabled"
                                {% if settings.oauth_enabled == "true" %}checked{% endif %}>
                            <div>
                                <span class="label-text font-semibold">{{ oauth_enabled_label }}</span>
                                <span class="label-text-alt block">{{ oauth_enabled_desc }}</span>
                            </div>
                        </label>
                    </div>

                    <!-- OAuth global options (shown when OAuth is enabled) -->
                    <div id="oauthGlobalOptions" class="space-y-4">
                        <!-- Base redirect URL -->
                        <div class="form-control">
                            <label class="label"><span class="label-text font-semibold">{{ oauth_redirect_url_label }}</span></label>
                            <input type="text" name="oauth_redirect_base_url" value="{{ settings.oauth_redirect_base_url }}"
                                placeholder="https://myapp.example.com" class="input input-bordered w-full">
                            <label class="label"><span class="label-text-alt">{{ oauth_redirect_url_desc }}</span></label>
                        </div>

                        <!-- Auto-register & Link existing toggles -->
                        <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                            <div class="form-control">
                                <label class="label cursor-pointer justify-start gap-4">
                                    <input type="checkbox" name="oauth_auto_register" value="true" class="toggle toggle-secondary"
                                        {% if settings.oauth_auto_register == "true" %}checked{% endif %}>
                                    <div>
                                        <span class="label-text font-semibold">{{ oauth_auto_register_label }}</span>
                                        <span class="label-text-alt block">{{ oauth_auto_register_desc }}</span>
                                    </div>
                                </label>
                            </div>
                            <div class="form-control">
                                <label class="label cursor-pointer justify-start gap-4">
                                    <input type="checkbox" name="oauth_link_existing_account" value="true" class="toggle toggle-secondary"
                                        {% if settings.oauth_link_existing_account == "true" %}checked{% endif %}>
                                    <div>
                                        <span class="label-text font-semibold">{{ oauth_link_existing_label }}</span>
                                        <span class="label-text-alt block">{{ oauth_link_existing_desc }}</span>
                                    </div>
                                </label>
                            </div>
                        </div>

                        <div class="divider my-2"></div>

                        <!-- ===== Google ===== -->
                        <div class="collapse collapse-arrow bg-base-200 rounded-box" id="collapseGoogle">
                            <input type="checkbox" class="peer oauth-provider-collapse" data-provider="google"
                                {% if settings.oauth_google_enabled == "true" %}checked{% endif %} />
                            <div class="collapse-title flex items-center gap-3">
                                <svg class="h-5 w-5" viewBox="0 0 24 24"><path fill="currentColor" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 0 1-2.2 3.32v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.1z"/><path fill="currentColor" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"/><path fill="currentColor" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"/><path fill="currentColor" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"/></svg>
                                <span class="font-semibold">{{ oauth_google_label }}</span>
                                <span class="badge badge-sm badge-outline ml-1">{{ oauth_google_desc }}</span>
                                <input type="checkbox" name="oauth_google_enabled" value="true" class="toggle toggle-primary toggle-sm ml-auto oauth-provider-toggle"
                                    data-provider="google"
                                    {% if settings.oauth_google_enabled == "true" %}checked{% endif %}
                                    onclick="event.stopPropagation()">
                            </div>
                            <div class="collapse-content space-y-3">
                                <div class="form-control">
                                    <label class="label"><span class="label-text">{{ oauth_client_id }}</span></label>
                                    <input type="text" name="oauth_google_client_id" value="{{ settings.oauth_google_client_id }}"
                                        placeholder="xxxx.apps.googleusercontent.com" class="input input-bordered input-sm w-full">
                                </div>
                                <div class="form-control">
                                    <label class="label">
                                        <span class="label-text">{{ oauth_client_secret }}</span>
                                        {% if settings.oauth_google_has_secret %}
                                        <span class="badge badge-success badge-sm gap-1">
                                            <svg xmlns="http://www.w3.org/2000/svg" class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" /></svg>
                                            {{ oauth_secret_configured }}
                                        </span>
                                        {% else %}
                                        <span class="badge badge-warning badge-sm">{{ oauth_secret_not_configured }}</span>
                                        {% endif %}
                                    </label>
                                    <input type="password" name="oauth_google_client_secret"
                                        placeholder="{% if settings.oauth_google_has_secret %}{{ oauth_secret_change }}{% else %}GOCSPX-...{% endif %}"
                                        class="input input-bordered input-sm w-full" autocomplete="off">
                                </div>
                                <div class="form-control">
                                    <label class="label"><span class="label-text">{{ oauth_redirect_uri }}</span></label>
                                    <div class="join w-full">
                                        <input type="text" readonly
                                            value="{{ settings.oauth_redirect_base_url }}/api/v1/auth/oauth/google/callback"
                                            class="input input-bordered input-sm join-item w-full bg-base-200 font-mono text-xs" id="googleRedirectUri">
                                        <button type="button" class="btn btn-sm join-item btn-outline copy-uri-btn" data-target="googleRedirectUri">{{ oauth_copy_uri }}</button>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <!-- ===== GitHub ===== -->
                        <div class="collapse collapse-arrow bg-base-200 rounded-box" id="collapseGithub">
                            <input type="checkbox" class="peer oauth-provider-collapse" data-provider="github"
                                {% if settings.oauth_github_enabled == "true" %}checked{% endif %} />
                            <div class="collapse-title flex items-center gap-3">
                                <svg class="h-5 w-5" viewBox="0 0 24 24"><path fill="currentColor" d="M12 .3a12 12 0 0 0-3.8 23.38c.6.12.83-.26.83-.57L9 21.07c-3.34.72-4.04-1.61-4.04-1.61-.55-1.39-1.34-1.76-1.34-1.76-1.08-.74.09-.73.09-.73 1.2.09 1.84 1.24 1.84 1.24 1.07 1.83 2.81 1.3 3.5 1 .1-.78.42-1.3.76-1.6-2.67-.3-5.47-1.33-5.47-5.93 0-1.31.47-2.38 1.24-3.22-.14-.3-.54-1.52.1-3.18 0 0 1-.32 3.3 1.23a11.5 11.5 0 0 1 6.02 0c2.28-1.55 3.29-1.23 3.29-1.23.64 1.66.24 2.88.12 3.18a4.65 4.65 0 0 1 1.23 3.22c0 4.61-2.8 5.63-5.48 5.92.42.36.81 1.1.81 2.22l-.01 3.29c0 .31.2.69.82.57A12 12 0 0 0 12 .3z"/></svg>
                                <span class="font-semibold">{{ oauth_github_label }}</span>
                                <span class="badge badge-sm badge-outline ml-1">{{ oauth_github_desc }}</span>
                                <input type="checkbox" name="oauth_github_enabled" value="true" class="toggle toggle-primary toggle-sm ml-auto oauth-provider-toggle"
                                    data-provider="github"
                                    {% if settings.oauth_github_enabled == "true" %}checked{% endif %}
                                    onclick="event.stopPropagation()">
                            </div>
                            <div class="collapse-content space-y-3">
                                <div class="form-control">
                                    <label class="label"><span class="label-text">{{ oauth_client_id }}</span></label>
                                    <input type="text" name="oauth_github_client_id" value="{{ settings.oauth_github_client_id }}"
                                        placeholder="Iv1.xxxxxx" class="input input-bordered input-sm w-full">
                                </div>
                                <div class="form-control">
                                    <label class="label">
                                        <span class="label-text">{{ oauth_client_secret }}</span>
                                        {% if settings.oauth_github_has_secret %}
                                        <span class="badge badge-success badge-sm gap-1">
                                            <svg xmlns="http://www.w3.org/2000/svg" class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" /></svg>
                                            {{ oauth_secret_configured }}
                                        </span>
                                        {% else %}
                                        <span class="badge badge-warning badge-sm">{{ oauth_secret_not_configured }}</span>
                                        {% endif %}
                                    </label>
                                    <input type="password" name="oauth_github_client_secret"
                                        placeholder="{% if settings.oauth_github_has_secret %}{{ oauth_secret_change }}{% else %}ghp_...{% endif %}"
                                        class="input input-bordered input-sm w-full" autocomplete="off">
                                </div>
                                <div class="form-control">
                                    <label class="label"><span class="label-text">{{ oauth_redirect_uri }}</span></label>
                                    <div class="join w-full">
                                        <input type="text" readonly
                                            value="{{ settings.oauth_redirect_base_url }}/api/v1/auth/oauth/github/callback"
                                            class="input input-bordered input-sm join-item w-full bg-base-200 font-mono text-xs" id="githubRedirectUri">
                                        <button type="button" class="btn btn-sm join-item btn-outline copy-uri-btn" data-target="githubRedirectUri">{{ oauth_copy_uri }}</button>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <!-- ===== Discord ===== -->
                        <div class="collapse collapse-arrow bg-base-200 rounded-box" id="collapseDiscord">
                            <input type="checkbox" class="peer oauth-provider-collapse" data-provider="discord"
                                {% if settings.oauth_discord_enabled == "true" %}checked{% endif %} />
                            <div class="collapse-title flex items-center gap-3">
                                <svg class="h-5 w-5" viewBox="0 0 24 24"><path fill="currentColor" d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"/></svg>
                                <span class="font-semibold">{{ oauth_discord_label }}</span>
                                <span class="badge badge-sm badge-outline ml-1">{{ oauth_discord_desc }}</span>
                                <input type="checkbox" name="oauth_discord_enabled" value="true" class="toggle toggle-primary toggle-sm ml-auto oauth-provider-toggle"
                                    data-provider="discord"
                                    {% if settings.oauth_discord_enabled == "true" %}checked{% endif %}
                                    onclick="event.stopPropagation()">
                            </div>
                            <div class="collapse-content space-y-3">
                                <div class="form-control">
                                    <label class="label"><span class="label-text">{{ oauth_client_id }}</span></label>
                                    <input type="text" name="oauth_discord_client_id" value="{{ settings.oauth_discord_client_id }}"
                                        placeholder="123456789012345678" class="input input-bordered input-sm w-full">
                                </div>
                                <div class="form-control">
                                    <label class="label">
                                        <span class="label-text">{{ oauth_client_secret }}</span>
                                        {% if settings.oauth_discord_has_secret %}
                                        <span class="badge badge-success badge-sm gap-1">
                                            <svg xmlns="http://www.w3.org/2000/svg" class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" /></svg>
                                            {{ oauth_secret_configured }}
                                        </span>
                                        {% else %}
                                        <span class="badge badge-warning badge-sm">{{ oauth_secret_not_configured }}</span>
                                        {% endif %}
                                    </label>
                                    <input type="password" name="oauth_discord_client_secret"
                                        placeholder="{% if settings.oauth_discord_has_secret %}{{ oauth_secret_change }}{% endif %}"
                                        class="input input-bordered input-sm w-full" autocomplete="off">
                                </div>
                                <div class="form-control">
                                    <label class="label"><span class="label-text">{{ oauth_redirect_uri }}</span></label>
                                    <div class="join w-full">
                                        <input type="text" readonly
                                            value="{{ settings.oauth_redirect_base_url }}/api/v1/auth/oauth/discord/callback"
                                            class="input input-bordered input-sm join-item w-full bg-base-200 font-mono text-xs" id="discordRedirectUri">
                                        <button type="button" class="btn btn-sm join-item btn-outline copy-uri-btn" data-target="discordRedirectUri">{{ oauth_copy_uri }}</button>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <!-- ===== Microsoft ===== -->
                        <div class="collapse collapse-arrow bg-base-200 rounded-box" id="collapseMicrosoft">
                            <input type="checkbox" class="peer oauth-provider-collapse" data-provider="microsoft"
                                {% if settings.oauth_microsoft_enabled == "true" %}checked{% endif %} />
                            <div class="collapse-title flex items-center gap-3">
                                <svg class="h-5 w-5" viewBox="0 0 24 24"><path fill="#f25022" d="M1 1h10v10H1z"/><path fill="#00a4ef" d="M1 13h10v10H1z"/><path fill="#7fba00" d="M13 1h10v10H13z"/><path fill="#ffb900" d="M13 13h10v10H13z"/></svg>
                                <span class="font-semibold">{{ oauth_microsoft_label }}</span>
                                <span class="badge badge-sm badge-outline ml-1">{{ oauth_microsoft_desc }}</span>
                                <input type="checkbox" name="oauth_microsoft_enabled" value="true" class="toggle toggle-primary toggle-sm ml-auto oauth-provider-toggle"
                                    data-provider="microsoft"
                                    {% if settings.oauth_microsoft_enabled == "true" %}checked{% endif %}
                                    onclick="event.stopPropagation()">
                            </div>
                            <div class="collapse-content space-y-3">
                                <div class="form-control">
                                    <label class="label"><span class="label-text">{{ oauth_client_id }}</span></label>
                                    <input type="text" name="oauth_microsoft_client_id" value="{{ settings.oauth_microsoft_client_id }}"
                                        placeholder="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" class="input input-bordered input-sm w-full">
                                </div>
                                <div class="form-control">
                                    <label class="label">
                                        <span class="label-text">{{ oauth_client_secret }}</span>
                                        {% if settings.oauth_microsoft_has_secret %}
                                        <span class="badge badge-success badge-sm gap-1">
                                            <svg xmlns="http://www.w3.org/2000/svg" class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" /></svg>
                                            {{ oauth_secret_configured }}
                                        </span>
                                        {% else %}
                                        <span class="badge badge-warning badge-sm">{{ oauth_secret_not_configured }}</span>
                                        {% endif %}
                                    </label>
                                    <input type="password" name="oauth_microsoft_client_secret"
                                        placeholder="{% if settings.oauth_microsoft_has_secret %}{{ oauth_secret_change }}{% endif %}"
                                        class="input input-bordered input-sm w-full" autocomplete="off">
                                </div>
                                <div class="form-control">
                                    <label class="label"><span class="label-text">{{ oauth_tenant }}</span></label>
                                    <input type="text" name="oauth_microsoft_tenant" value="{{ settings.oauth_microsoft_tenant }}"
                                        placeholder="common" class="input input-bordered input-sm w-full">
                                </div>
                                <div class="form-control">
                                    <label class="label"><span class="label-text">{{ oauth_redirect_uri }}</span></label>
                                    <div class="join w-full">
                                        <input type="text" readonly
                                            value="{{ settings.oauth_redirect_base_url }}/api/v1/auth/oauth/microsoft/callback"
                                            class="input input-bordered input-sm join-item w-full bg-base-200 font-mono text-xs" id="microsoftRedirectUri">
                                        <button type="button" class="btn btn-sm join-item btn-outline copy-uri-btn" data-target="microsoftRedirectUri">{{ oauth_copy_uri }}</button>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

                    <!-- Restart warning -->
                    <div class="alert alert-warning mt-4">
                        <svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" /></svg>
                        <span class="text-sm">{{ oauth_restart_warning }}</span>
                    </div>

                    <div class="alert alert-info mt-2">
                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="stroke-current shrink-0 w-6 h-6"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
                        <span class="text-sm">{{ oauth_env_info }}</span>
                    </div>
                </div>
            </div>
        </div>

        <!-- Audience Measurement Card -->
        <div class="card bg-base-100 shadow-xl">
            <div class="card-body">
                <h2 class="card-title text-xl mb-4">
                    <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" /></svg>
                    {{ analytics_title }}
                </h2>
                <p class="text-sm text-base-content/70 mb-4">{{ analytics_desc }}</p>

                {% if settings.analytics_configured %}
                <!-- Script URL: read-only, it feeds the CSP which is frozen at startup. -->
                <div class="form-control mb-4">
                    <label class="label">
                        <span class="label-text font-semibold">{{ analytics_script_url_label }}</span>
                    </label>
                    <input
                        type="text"
                        class="input input-bordered w-full font-mono text-sm"
                        value="{{ settings.analytics_script_url }}"
                        readonly
                        disabled
                    />
                    <label class="label">
                        <span class="label-text-alt text-base-content/60">{{ analytics_script_url_desc }}</span>
                    </label>
                </div>

                <div class="form-control mb-4">
                    <label class="label cursor-pointer justify-start gap-4">
                        <input
                            type="checkbox"
                            name="analytics_enabled"
                            value="true"
                            class="toggle toggle-primary"
                            {% if settings.analytics_enabled == "true" %}checked{% endif %}
                        />
                        <div>
                            <span class="label-text font-semibold">{{ analytics_enabled_label }}</span>
                            <p class="text-xs text-base-content/60 mt-1">{{ analytics_enabled_desc }}</p>
                        </div>
                    </label>
                </div>

                <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                    <div class="form-control">
                        <label class="label">
                            <span class="label-text font-semibold">{{ analytics_site_id_label }}</span>
                        </label>
                        <input
                            type="text"
                            name="analytics_site_id"
                            class="input input-bordered w-full"
                            value="{{ settings.analytics_site_id }}"
                        />
                        <label class="label">
                            <span class="label-text-alt text-base-content/60">{{ analytics_site_id_desc }}</span>
                        </label>
                    </div>

                    <div class="form-control">
                        <label class="label">
                            <span class="label-text font-semibold">{{ analytics_attributes_label }}</span>
                        </label>
                        <input
                            type="text"
                            name="analytics_attributes"
                            class="input input-bordered w-full font-mono text-sm"
                            value="{{ settings.analytics_attributes }}"
                        />
                        <label class="label">
                            <span class="label-text-alt text-base-content/60">{{ analytics_attributes_desc }}</span>
                        </label>
                    </div>
                </div>
                {% else %}
                <div class="alert alert-info">
                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="stroke-current shrink-0 w-6 h-6"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
                    <span class="text-sm">{{ analytics_not_configured }}</span>
                </div>
                {% endif %}
            </div>
        </div>

        <!-- Action Buttons -->
        <div class="card bg-base-200 shadow-xl">
            <div class="card-body">
                <div class="flex justify-between items-center">
                    <div>
                        <h3 class="font-semibold">{{ save_changes }}</h3>
                        <p class="text-sm text-base-content/70">{{ save_changes_desc }}</p>
                    </div>
                    <div class="flex gap-2">
                        <a href="/admin" class="btn btn-ghost">{{ cancel }}</a>
                        <button type="submit" class="btn btn-primary">
                            <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" /></svg>
                            {{ save_button }}
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </form>
</div>

<script>
const expirationCheckbox = document.getElementById('expirationEnabled');
const expirationSettings = document.getElementById('expirationSettings');

function toggleExpirationSettings() {
    if (expirationCheckbox.checked) {
        expirationSettings.classList.remove('hidden');
    } else {
        expirationSettings.classList.add('hidden');
    }
}

if (expirationCheckbox) {
    expirationCheckbox.addEventListener('change', toggleExpirationSettings);
    toggleExpirationSettings();
}

const oauthCheckbox = document.getElementById('oauthEnabled');
const oauthGlobalOptions = document.getElementById('oauthGlobalOptions');

function toggleOauthSection() {
    if (oauthCheckbox && oauthGlobalOptions) {
        if (oauthCheckbox.checked) {
            oauthGlobalOptions.classList.remove('hidden', 'opacity-50');
            oauthGlobalOptions.style.pointerEvents = '';
        } else {
            oauthGlobalOptions.classList.add('hidden');
        }
    }
}

if (oauthCheckbox) {
    oauthCheckbox.addEventListener('change', toggleOauthSection);
    toggleOauthSection();
}

document.querySelectorAll('.copy-uri-btn').forEach(function(btn) {
    btn.addEventListener('click', function() {
        var target = document.getElementById(this.dataset.target);
        if (target) {
            navigator.clipboard.writeText(target.value).then(function() {
                btn.textContent = '✓';
                setTimeout(function() { btn.textContent = '{{ oauth_copy_uri }}'; }, 1500);
            });
        }
    });
});

document.getElementById('settingsForm').addEventListener('submit', async function(e) {
    e.preventDefault();
    
    const formData = new FormData(this);
    const submitBtn = this.querySelector('button[type="submit"]');
    
    submitBtn.disabled = true;
    submitBtn.innerHTML = '<span class="loading loading-spinner"></span> {{ saving }}';
    
    try {
        const response = await fetch('/admin/settings', {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
                'X-CSRF-Token': '{{ csrf_token }}',
            },
            body: new URLSearchParams(formData)
        });
        
        const result = await response.json();
        
        if (response.ok) {
            alert('✅ {{ save_success }}');
            window.location.reload();
        } else {
            alert('❌ {{ save_error_prefix }} : ' + (result.error || result.message || ''));
            submitBtn.disabled = false;
            submitBtn.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" /></svg> {{ save_button }}';
        }
    } catch (error) {
        console.error('Error:', error);
        alert('❌ {{ network_error }}');
        submitBtn.disabled = false;
        submitBtn.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" /></svg> {{ save_button }}';
    }
});
</script>
{% endblock %}