{"version":3,"file":"category_controller.js","sources":["../../../assets/controllers/admin/category_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus';\nimport Sortable from 'sortablejs';\n\ninterface CategoryPayload {\n    id: number;\n    name: string;\n    slug: string;\n    description?: string | null;\n    imageUrl?: string | null;\n    visible: boolean;\n    position?: number;\n    isSystem: boolean;\n}\n\ninterface SubcategoryPayload {\n    id: number;\n    name: string;\n    slug: string;\n    imageUrl?: string | null;\n    visible: boolean;\n    position?: number;\n    categoryId: number;\n    categoryName: string;\n    isSystem: boolean;\n}\n\ntype ModalMode = 'category' | 'subcategory';\ntype ModalPurpose = 'create' | 'edit';\n\nexport default class extends Controller {\n    static targets = [\n        'modal',\n        'modalTitle',\n        'modalForm',\n        'modalEntityId',\n        'modalMode',\n        'nameInput',\n        'nameError',\n        'slugInput',\n        'slugWarning',\n        'slugError',\n        'descriptionWrapper',\n        'descriptionInput',\n        'parentCategoryWrapper',\n        'parentCategorySelect',\n        'imagePreview',\n        'imageInput',\n        'imageError',\n        'removeImageBtn',\n        'removeImageInput',\n        'visibleInput',\n        'systemNotice',\n        'submitButton',\n        'deleteDialog',\n        'deleteMessage',\n        'deleteImpact',\n        'deleteConfirmBtn',\n        'toast',\n        'toastMessage',\n    ];\n\n    declare modalTarget: HTMLDialogElement;\n    declare modalTitleTarget: HTMLElement;\n    declare modalFormTarget: HTMLFormElement;\n    declare modalEntityIdTarget: HTMLInputElement;\n    declare modalModeTarget: HTMLInputElement;\n    declare nameInputTarget: HTMLInputElement;\n    declare nameErrorTarget: HTMLElement;\n    declare slugInputTarget: HTMLInputElement;\n    declare slugWarningTarget: HTMLElement;\n    declare slugErrorTarget: HTMLElement;\n    declare descriptionWrapperTarget: HTMLElement;\n    declare descriptionInputTarget: HTMLTextAreaElement;\n    declare parentCategoryWrapperTarget: HTMLElement;\n    declare parentCategorySelectTarget: HTMLSelectElement;\n    declare imagePreviewTarget: HTMLImageElement;\n    declare imageInputTarget: HTMLInputElement;\n    declare imageErrorTarget: HTMLElement;\n    declare removeImageBtnTarget: HTMLButtonElement;\n    declare removeImageInputTarget: HTMLInputElement;\n    declare visibleInputTarget: HTMLInputElement;\n    declare systemNoticeTarget: HTMLElement;\n    declare submitButtonTarget: HTMLButtonElement;\n    declare deleteDialogTarget: HTMLDialogElement;\n    declare deleteMessageTarget: HTMLElement;\n    declare deleteImpactTarget: HTMLElement;\n    declare deleteConfirmBtnTarget: HTMLButtonElement;\n    declare toastTarget: HTMLElement;\n    declare toastMessageTarget: HTMLElement;\n\n    private mode: ModalMode = 'category';\n    private purpose: ModalPurpose = 'create';\n    private editingId: number | null = null;\n    private parentCategoryId: number | null = null;\n    private initialSlug: string = '';\n    private slugTouched: boolean = false;\n    private nameTouched: boolean = false;\n    private dirty: boolean = false;\n    private currentImageUrl: string | null = null;\n    private pendingDelete: { type: ModalMode; id: number } | null = null;\n\n    connect(): void {\n        this.modalFormTarget.addEventListener('change', () => {\n            this.dirty = true;\n        });\n        this.initSortable();\n    }\n\n    private initSortable(): void {\n        const categoriesList = this.element.querySelector<HTMLElement>('[data-sortable-categories]');\n        if (categoriesList) {\n            Sortable.create(categoriesList, {\n                handle: '.sortable-handle',\n                filter: '.is-system',\n                animation: 150,\n                onEnd: () => this.persistCategoryOrder(categoriesList),\n            });\n        }\n        const subLists = this.element.querySelectorAll<HTMLElement>('[data-sortable-subcategories]');\n        subLists.forEach((list) => {\n            Sortable.create(list, {\n                handle: '.sortable-handle',\n                filter: '.is-system',\n                animation: 150,\n                onEnd: () => this.persistSubcategoryOrder(list),\n            });\n        });\n    }\n\n    private async persistCategoryOrder(list: HTMLElement): Promise<void> {\n        const ids = Array.from(list.querySelectorAll<HTMLElement>(':scope > [data-category-id]'))\n            .filter((el) => !el.classList.contains('is-system'))\n            .map((el) => parseInt(el.dataset.categoryId || '0', 10))\n            .filter((n) => n > 0);\n        if (ids.length === 0) return;\n        const res = await fetch('/api/admin/categories/reorder', {\n            method: 'PATCH',\n            headers: { 'Content-Type': 'application/json' },\n            body: JSON.stringify({ ids }),\n        });\n        if (!res.ok) {\n            this.showToast('Erreur lors du réordonnancement', 'error');\n            window.location.reload();\n        }\n    }\n\n    private async persistSubcategoryOrder(list: HTMLElement): Promise<void> {\n        const categoryId = parseInt(list.dataset.categoryId || '0', 10);\n        if (!categoryId) return;\n        const ids = Array.from(list.querySelectorAll<HTMLElement>(':scope > [data-subcategory-id]'))\n            .filter((el) => !el.classList.contains('is-system'))\n            .map((el) => parseInt(el.dataset.subcategoryId || '0', 10))\n            .filter((n) => n > 0);\n        if (ids.length === 0) return;\n        const res = await fetch(`/api/admin/categories/${categoryId}/subcategories/reorder`, {\n            method: 'PATCH',\n            headers: { 'Content-Type': 'application/json' },\n            body: JSON.stringify({ ids }),\n        });\n        if (!res.ok) {\n            this.showToast('Erreur lors du réordonnancement', 'error');\n            window.location.reload();\n        }\n    }\n\n    // ---------------------------------------------------------------\n    // Modal open / close\n    // ---------------------------------------------------------------\n\n    openCreateModal(): void {\n        this.resetModal();\n        this.mode = 'category';\n        this.purpose = 'create';\n        this.modalModeTarget.value = 'category';\n        this.modalTitleTarget.textContent = 'Ajouter une catégorie';\n        this.parentCategoryWrapperTarget.classList.add('hidden');\n        this.descriptionWrapperTarget.classList.remove('hidden');\n        this.openDialog();\n    }\n\n    async openEditModal(event: Event): Promise<void> {\n        const target = event.currentTarget as HTMLElement;\n        const id = parseInt(target.dataset.categoryId || '0', 10);\n        if (!id) return;\n\n        this.resetModal();\n        this.mode = 'category';\n        this.purpose = 'edit';\n        this.editingId = id;\n        this.modalModeTarget.value = 'category';\n        this.modalTitleTarget.textContent = 'Modifier la catégorie';\n        this.parentCategoryWrapperTarget.classList.add('hidden');\n        this.descriptionWrapperTarget.classList.remove('hidden');\n\n        try {\n            const res = await fetch(`/api/admin/categories/${id}`);\n            if (!res.ok) throw new Error('not found');\n            const data: CategoryPayload = await res.json();\n            this.populateCategory(data);\n            this.openDialog();\n        } catch {\n            this.showToast('Catégorie introuvable', 'error');\n        }\n    }\n\n    openSubcategoryCreateModal(event: Event): void {\n        const target = event.currentTarget as HTMLElement;\n        const parentId = parseInt(target.dataset.categoryId || '0', 10);\n        if (!parentId) return;\n\n        this.resetModal();\n        this.mode = 'subcategory';\n        this.purpose = 'create';\n        this.parentCategoryId = parentId;\n        this.modalModeTarget.value = 'subcategory';\n        this.modalTitleTarget.textContent = 'Ajouter une sous-catégorie';\n        this.parentCategoryWrapperTarget.classList.remove('hidden');\n        this.descriptionWrapperTarget.classList.add('hidden');\n        this.populateParentCategorySelect(parentId);\n        this.openDialog();\n    }\n\n    async openSubcategoryEditModal(event: Event): Promise<void> {\n        const target = event.currentTarget as HTMLElement;\n        const id = parseInt(target.dataset.subcategoryId || '0', 10);\n        if (!id) return;\n\n        this.resetModal();\n        this.mode = 'subcategory';\n        this.purpose = 'edit';\n        this.editingId = id;\n        this.modalModeTarget.value = 'subcategory';\n        this.modalTitleTarget.textContent = 'Modifier la sous-catégorie';\n        this.parentCategoryWrapperTarget.classList.remove('hidden');\n        this.descriptionWrapperTarget.classList.add('hidden');\n\n        try {\n            const res = await fetch(`/api/admin/subcategories/${id}`);\n            if (!res.ok) throw new Error('not found');\n            const data: SubcategoryPayload = await res.json();\n            this.populateParentCategorySelect(data.categoryId);\n            this.populateSubcategory(data);\n            this.openDialog();\n        } catch {\n            this.showToast('Sous-catégorie introuvable', 'error');\n        }\n    }\n\n    private openDialog(): void {\n        this.dirty = false;\n        this.modalTarget.showModal();\n        // Refresh the rich-text editor from the (just-populated or reset)\n        // description textarea — see common--rich-text#syncFromSource.\n        window.dispatchEvent(new CustomEvent('richtext:sync'));\n        setTimeout(() => this.nameInputTarget.focus(), 0);\n    }\n\n    cancelModal(event?: Event): void {\n        if (event) event.preventDefault();\n        if (this.dirty && !confirm('Des modifications non enregistrées seront perdues. Fermer ?')) {\n            return;\n        }\n        this.modalTarget.close();\n    }\n\n    private resetModal(): void {\n        this.editingId = null;\n        this.parentCategoryId = null;\n        this.initialSlug = '';\n        this.slugTouched = false;\n        this.nameTouched = false;\n        this.dirty = false;\n        this.currentImageUrl = null;\n        this.modalFormTarget.reset();\n        this.modalEntityIdTarget.value = '';\n        this.nameErrorTarget.classList.add('hidden');\n        this.slugErrorTarget.classList.add('hidden');\n        this.slugWarningTarget.classList.add('hidden');\n        this.imageErrorTarget.classList.add('hidden');\n        this.imagePreviewTarget.classList.add('hidden');\n        this.imagePreviewTarget.src = '';\n        this.removeImageBtnTarget.classList.add('hidden');\n        this.removeImageInputTarget.value = '0';\n        this.visibleInputTarget.checked = true;\n        this.visibleInputTarget.disabled = false;\n        this.systemNoticeTarget.classList.add('hidden');\n        this.submitButtonTarget.disabled = false;\n    }\n\n    private populateCategory(data: CategoryPayload): void {\n        this.modalEntityIdTarget.value = String(data.id);\n        this.nameInputTarget.value = data.name;\n        this.slugInputTarget.value = data.slug;\n        this.descriptionInputTarget.value = data.description ?? '';\n        this.visibleInputTarget.checked = data.visible;\n        this.initialSlug = data.slug;\n        this.slugTouched = true;\n        this.nameTouched = true;\n        this.currentImageUrl = data.imageUrl ?? null;\n        if (data.imageUrl) {\n            this.imagePreviewTarget.src = data.imageUrl;\n            this.imagePreviewTarget.classList.remove('hidden');\n            this.removeImageBtnTarget.classList.remove('hidden');\n        }\n        if (data.isSystem) {\n            this.visibleInputTarget.disabled = true;\n            this.slugInputTarget.disabled = true;\n            this.systemNoticeTarget.classList.remove('hidden');\n        }\n    }\n\n    private populateSubcategory(data: SubcategoryPayload): void {\n        this.modalEntityIdTarget.value = String(data.id);\n        this.nameInputTarget.value = data.name;\n        this.slugInputTarget.value = data.slug;\n        this.visibleInputTarget.checked = data.visible;\n        this.initialSlug = data.slug;\n        this.slugTouched = true;\n        this.nameTouched = true;\n        this.parentCategoryId = data.categoryId;\n        this.parentCategorySelectTarget.value = String(data.categoryId);\n        this.currentImageUrl = data.imageUrl ?? null;\n        if (data.imageUrl) {\n            this.imagePreviewTarget.src = data.imageUrl;\n            this.imagePreviewTarget.classList.remove('hidden');\n            this.removeImageBtnTarget.classList.remove('hidden');\n        }\n        if (data.isSystem) {\n            this.visibleInputTarget.disabled = true;\n            this.slugInputTarget.disabled = true;\n            this.parentCategorySelectTarget.disabled = true;\n            this.systemNoticeTarget.classList.remove('hidden');\n        }\n    }\n\n    private populateParentCategorySelect(selectedId: number): void {\n        this.parentCategorySelectTarget.innerHTML = '';\n        const items = this.element.querySelectorAll<HTMLElement>('[data-category-id][data-category-name]');\n        const seen = new Set<number>();\n        items.forEach((item) => {\n            const id = parseInt(item.dataset.categoryId || '0', 10);\n            const name = item.dataset.categoryName || '';\n            if (!id || seen.has(id) || item.classList.contains('is-system')) return;\n            seen.add(id);\n            const opt = document.createElement('option');\n            opt.value = String(id);\n            opt.textContent = name;\n            if (id === selectedId) opt.selected = true;\n            this.parentCategorySelectTarget.appendChild(opt);\n        });\n    }\n\n    // ---------------------------------------------------------------\n    // Form interactions\n    // ---------------------------------------------------------------\n\n    onNameInput(): void {\n        if (!this.slugTouched) {\n            this.slugInputTarget.value = this.slugify(this.nameInputTarget.value);\n        }\n        this.nameTouched = true;\n    }\n\n    onSlugInput(): void {\n        this.slugTouched = true;\n        const current = this.slugInputTarget.value;\n        if (this.purpose === 'edit' && this.initialSlug && current !== this.initialSlug) {\n            this.slugWarningTarget.classList.remove('hidden');\n        } else {\n            this.slugWarningTarget.classList.add('hidden');\n        }\n    }\n\n    onImageSelected(): void {\n        const file = this.imageInputTarget.files?.[0];\n        if (!file) return;\n        this.imagePreviewTarget.src = URL.createObjectURL(file);\n        this.imagePreviewTarget.classList.remove('hidden');\n        this.removeImageBtnTarget.classList.remove('hidden');\n        this.removeImageInputTarget.value = '0';\n        this.dirty = true;\n    }\n\n    removeCurrentImage(): void {\n        this.imageInputTarget.value = '';\n        this.imagePreviewTarget.src = '';\n        this.imagePreviewTarget.classList.add('hidden');\n        this.removeImageBtnTarget.classList.add('hidden');\n        this.removeImageInputTarget.value = '1';\n        this.dirty = true;\n    }\n\n    private slugify(input: string): string {\n        return input\n            .normalize('NFD')\n            .replace(/[̀-ͯ]/g, '')\n            .toLowerCase()\n            .replace(/[^a-z0-9]+/g, '-')\n            .replace(/^-+|-+$/g, '');\n    }\n\n    // ---------------------------------------------------------------\n    // Submit\n    // ---------------------------------------------------------------\n\n    async submitModal(event: Event): Promise<void> {\n        event.preventDefault();\n        this.clearFieldErrors();\n\n        const formData = new FormData();\n        formData.append('name', this.nameInputTarget.value.trim());\n        formData.append('slug', this.slugInputTarget.value.trim());\n        formData.append('visible', this.visibleInputTarget.checked ? '1' : '0');\n\n        if (this.mode === 'category') {\n            // Description (rich text) is category-only — subcategories have none.\n            formData.append('description', this.descriptionInputTarget.value);\n        } else {\n            const parent = this.parentCategorySelectTarget.value;\n            if (parent) formData.append('category', parent);\n        }\n\n        const file = this.imageInputTarget.files?.[0];\n        if (file) formData.append('image', file);\n        formData.append('removeImage', this.removeImageInputTarget.value);\n\n        let url: string;\n        let method: 'POST' | 'PATCH' = 'POST';\n        if (this.mode === 'category') {\n            url = this.purpose === 'create'\n                ? '/api/admin/categories'\n                : `/api/admin/categories/${this.editingId}`;\n            if (this.purpose === 'edit') {\n                formData.append('_method', 'PATCH');\n            }\n        } else {\n            if (this.purpose === 'create') {\n                const parentId = this.parentCategorySelectTarget.value || this.parentCategoryId;\n                url = `/api/admin/categories/${parentId}/subcategories`;\n            } else {\n                url = `/api/admin/subcategories/${this.editingId}`;\n                formData.append('_method', 'PATCH');\n            }\n        }\n\n        this.submitButtonTarget.disabled = true;\n        try {\n            const res = await fetch(url, { method, body: formData });\n            if (res.ok) {\n                const payload = await res.json();\n                this.modalTarget.close();\n                this.showToast(this.purpose === 'create' ? 'Créé avec succès' : 'Modifié avec succès', 'success');\n                window.location.reload();\n                return;\n            }\n\n            if (res.status === 422) {\n                const errors = await res.json();\n                this.applyFieldErrors(errors.errors || {});\n            } else if (res.status === 403) {\n                const data = await res.json();\n                this.showToast(data.error || 'Action interdite', 'error');\n            } else {\n                this.showToast('Erreur lors de l\\'enregistrement', 'error');\n            }\n        } catch {\n            this.showToast('Erreur réseau', 'error');\n        } finally {\n            this.submitButtonTarget.disabled = false;\n        }\n    }\n\n    private clearFieldErrors(): void {\n        this.nameErrorTarget.classList.add('hidden');\n        this.slugErrorTarget.classList.add('hidden');\n        this.imageErrorTarget.classList.add('hidden');\n    }\n\n    private applyFieldErrors(errors: Record<string, string[]>): void {\n        if (errors.name) {\n            this.nameErrorTarget.textContent = errors.name.join(' ');\n            this.nameErrorTarget.classList.remove('hidden');\n        }\n        if (errors.slug) {\n            this.slugErrorTarget.textContent = errors.slug.join(' ');\n            this.slugErrorTarget.classList.remove('hidden');\n        }\n        if (errors.image) {\n            this.imageErrorTarget.textContent = errors.image.join(' ');\n            this.imageErrorTarget.classList.remove('hidden');\n        }\n    }\n\n    // ---------------------------------------------------------------\n    // Delete\n    // ---------------------------------------------------------------\n\n    async deleteCategory(event: Event): Promise<void> {\n        const target = event.currentTarget as HTMLElement;\n        const id = parseInt(target.dataset.categoryId || '0', 10);\n        if (!id) return;\n        await this.requestDeleteImpact('category', id);\n    }\n\n    async deleteSubcategory(event: Event): Promise<void> {\n        const target = event.currentTarget as HTMLElement;\n        const id = parseInt(target.dataset.subcategoryId || '0', 10);\n        if (!id) return;\n        await this.requestDeleteImpact('subcategory', id);\n    }\n\n    private async requestDeleteImpact(type: ModalMode, id: number): Promise<void> {\n        const url = type === 'category'\n            ? `/api/admin/categories/${id}/deletion-impact`\n            : `/api/admin/subcategories/${id}/deletion-impact`;\n        try {\n            const res = await fetch(url);\n            if (!res.ok) {\n                this.showToast('Impossible de calculer l\\'impact', 'error');\n                return;\n            }\n            const data = await res.json();\n            this.pendingDelete = { type, id };\n            this.deleteMessageTarget.textContent = type === 'category'\n                ? 'Confirmer la suppression de cette catégorie ?'\n                : 'Confirmer la suppression de cette sous-catégorie ?';\n            const lines: string[] = [];\n            if (type === 'category') {\n                lines.push(`${data.subcategoriesCount} sous-catégorie(s) seront supprimée(s).`);\n            }\n            lines.push(`${data.productsToReassign} produit(s) seront ré-affecté(s) à « Non catégorisé ».`);\n            this.deleteImpactTarget.textContent = lines.join(' ');\n            this.deleteDialogTarget.showModal();\n        } catch {\n            this.showToast('Erreur réseau', 'error');\n        }\n    }\n\n    async confirmDelete(): Promise<void> {\n        if (!this.pendingDelete) return;\n        const { type, id } = this.pendingDelete;\n        this.deleteConfirmBtnTarget.disabled = true;\n        const url = type === 'category'\n            ? `/api/admin/categories/${id}`\n            : `/api/admin/subcategories/${id}`;\n        try {\n            const res = await fetch(url, { method: 'DELETE' });\n            if (res.ok) {\n                this.deleteDialogTarget.close();\n                this.showToast('Suppression effectuée', 'success');\n                window.location.reload();\n                return;\n            }\n            const data = await res.json().catch(() => ({}));\n            this.showToast(data.error || 'Erreur lors de la suppression', 'error');\n        } catch {\n            this.showToast('Erreur réseau', 'error');\n        } finally {\n            this.deleteConfirmBtnTarget.disabled = false;\n            this.pendingDelete = null;\n        }\n    }\n\n    cancelDelete(): void {\n        this.pendingDelete = null;\n        this.deleteDialogTarget.close();\n    }\n\n    // ---------------------------------------------------------------\n    // Toast\n    // ---------------------------------------------------------------\n\n    private showToast(message: string, kind: 'success' | 'error'): void {\n        this.toastMessageTarget.textContent = message;\n        this.toastTarget.classList.remove('hidden', 'alert-success', 'alert-error');\n        this.toastTarget.classList.add(kind === 'success' ? 'alert-success' : 'alert-error');\n        setTimeout(() => this.toastTarget.classList.add('hidden'), 3000);\n    }\n}\n"],"names":[],"mappings":"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"}