import {Meta, Canvas, Controls, Source} from '@storybook/blocks';
import * as ValidationStories from './DatePickerValidation.stories.ts';
import '../../../stories/styles/shared.css';

<Meta of={ValidationStories}/>

<div className="header">
  <h1>Documentations des règles de validation du DatePicker</h1>
  <p>Le composant DatePicker prend en charge plusieurs types de règles de validation qui permettent de contrôler les dates saisies par l'utilisateur. Cette documentation décrit toutes les règles disponibles et comment les utiliser.</p>
  <p>Pour les règles <code>notBeforeDate</code>, <code>notAfterDate</code> et <code>dateExact</code>, lorsque la date de référence est vide (valeur <code>null</code> ou chaîne vide), la règle est ignorée pour cette validation. Le message technique « Configuration de la règle invalide » n'est affiché que si l'option <code>date</code> est totalement absente de la configuration de la règle.</p>
</div>

> Pour en savoir plus sur le système global de gestion de validation, consultez la page <a href="/?path=/docs/guide-du-dev-utiliser-le-syst%C3%A8me-de-validation--docs">Utiliser le système de validation</a>.

## Exemples de validation

## Structure d'une règle de validation

Les règles de validation sont définies avec la structure suivante :

<Source
    dark code={`
{
  type: string, // Type de la règle (ex: 'notAfterToday')
  options: {
    message?: string, // Message d'erreur personnalisé
    successMessage?: string, // Message de succès personnalisé
    warningMessage?: string, // Message d'avertissement personnalisé
    fieldIdentifier?: string, // Identifiant du champ pour les messages
    // Autres options spécifiques au type de règle
  }
}
`}/>

Ces règles peuvent être passées au DatePicker via les props `customRules` (pour les erreurs) ou `customWarningRules` (pour les avertissements).

## Types de règles disponibles

### 1. `required`

Vérifie que la date est renseignée.

<Source
    dark code={`
<DatePicker
  v-model="date"
  :custom-rules="[{ 
    type: 'required',
    options: { 
      message: 'Vous devez sélectionner une date' 
    } 
  }]"
/>
`}/>

### 2. `notWeekend`

Vérifie que la date sélectionnée n'est pas un jour de weekend (samedi ou dimanche).

<Source
    dark code={`
<DatePicker
  v-model="date"
  :custom-rules="[{ 
    type: 'notWeekend', 
    options: { 
      message: 'La date ne peut pas être un weekend' 
    } 
  }]"
/>
`}/>

### 3. `notBeforeToday`

Vérifie que la date sélectionnée n'est pas antérieure à la date du jour.

<Source
    dark code={`
<DatePicker
  v-model="date"
  :custom-rules="[{ 
    type: 'notBeforeToday', 
    options: { 
      message: 'La date ne peut pas être antérieure à aujourd\'hui' 
    } 
  }]"
/>
`}/>

### 4. `notAfterToday`

Vérifie que la date sélectionnée n'est pas postérieure à la date du jour.

<Source
    dark code={`
<DatePicker
  v-model="date"
  :custom-rules="[{ 
    type: 'notAfterToday', 
    options: { 
      message: 'La date ne peut pas être postérieure à aujourd\'hui' 
    } 
  }]"
/>
`}/>

### 5. `notBeforeDate`

Vérifie que la date sélectionnée n'est pas antérieure à une date de référence.

<Source
    dark code={`
<DatePicker
  v-model="date"
  :custom-rules="[{ 
    type: 'notBeforeDate', 
    options: { 
      message: 'La date ne peut pas être antérieure au 01/01/2023',
      date: '01/01/2023' // Date de référence au format DD/MM/YYYY
    } 
  }]"
/>
`}/>

### 6. `notAfterDate`

Vérifie que la date sélectionnée n'est pas postérieure à une date de référence.

<Source
    dark code={`
<DatePicker
  v-model="date"
  :custom-rules="[{ 
    type: 'notAfterDate', 
    options: { 
      message: 'La date ne peut pas être postérieure au 31/12/2023',
      date: '31/12/2023' // Date de référence au format DD/MM/YYYY
    } 
  }]"
/>
`}/>

### 7. `dateExact`

Vérifie que la date sélectionnée est exactement égale à une date de référence.

<Source
    dark code={`
<DatePicker
  v-model="date"
  :custom-rules="[{ 
    type: 'dateExact', 
    options: { 
      message: 'La date doit être le 25/12/2023',
      date: '25/12/2023' // Date de référence au format DD/MM/YYYY
    } 
  }]"
/>
`}/>

#### Notes sur les dates de référence dynamiques

Lorsque l'option `date` d'une règle `notBeforeDate`, `notAfterDate` ou `dateExact` est fournie mais que sa valeur est vide (`null` ou chaîne vide), la règle est considérée comme inactive pour cette validation : aucun message d'erreur ou d'avertissement n'est affiché.

L'erreur technique « Configuration de la règle invalide » n'est affichée que si l'option `date` est totalement absente de la configuration de la règle (par exemple `{ type: 'notBeforeDate', options: {} }`).

### 8. `custom`

Permet de créer une règle de validation personnalisée avec une fonction de validation.

<Source
    dark code={`
<DatePicker
  v-model="date"
  :custom-rules="[{
    type: 'custom',
    options: {
      validate: (value) => {
        // Si pas de valeur, c'est valide
        if (!value) return true
        // Convertir en chaîne si ce n'est pas déjà le cas
        const dateStr = value.toString()
        // Vérifier si c'est une Date et extraire l'année
        if (value instanceof Date) {
          return value.getFullYear() !== 2024
        }
        // Fallback sur la vérification de chaîne
        return !dateStr.includes('2024')
      },
      message: 'Les dates en 2024 ne sont pas autorisées',
      successMessage: 'Date valide (hors 2024)',
      fieldIdentifier: 'date'
    }
  }]"
/>				
`}/>

La fonction `validate` reçoit la valeur de la date (au format spécifié par la prop `format`) et doit retourner :
- `true` si la validation réussit
- `false` ou une chaîne (message d'erreur personnalisé) si la validation échoue

## Utilisation des règles d'avertissement

Toutes les règles ci-dessus peuvent également être utilisées comme règles d'avertissement avec la prop `customWarningRules`. Les avertissements n'empêchent pas la soumission du formulaire mais affichent un message en orange.

<Source
    dark code={`
<DatePicker
  v-model="date"
  :custom-warning-rules="[{
    type: 'notBeforeDate',
    options: {
      warningMessage: 'Attention : la date est antérieure à la date de référence',
      date: '01/01/2024',
      isWarning: true
    }
  }]"
/>
`}/>

## Combinaison de plusieurs règles

Vous pouvez combiner plusieurs règles de validation :

<Source
    dark code={`
<DatePicker
  v-model="date"
  :custom-rules="[
    { 
      type: 'required', 
      options: { message: 'La date est requise.' } 
    },
    { 
      type: 'notWeekend', 
      options: { message: 'La date ne peut pas être un weekend.' } 
    },
    { 
      type: 'notAfterToday', 
      options: { message: 'La date ne peut pas être dans le futur.' } 
    }
  ]"
/>
`}/>

## Messages de succès

Vous pouvez personnaliser les messages de succès qui s'affichent lorsque la validation réussit :

<Source
    dark code={`
<DatePicker
  v-model="date"
  :custom-rules="[{ 
    type: 'notWeekend', 
    options: {
      message: 'La date ne peut pas être un weekend',
      successMessage: 'La date sélectionnée est valide (jour de semaine)'
    }
  }]"
  :show-success-messages="true"
/>
`}/>

Pour afficher les messages de succès, la prop `showSuccessMessages` doit être définie à `true`.

## Désactivation de la gestion des erreurs

Si vous souhaitez effectuer la validation sans afficher les messages d'erreur, vous pouvez utiliser la prop `disableErrorHandling` :

<Source
    dark code={`
<DatePicker
  v-model="date"
  :custom-rules="[{ type: 'required' }]"
  :disable-error-handling="true"
/>
`}/>

Cette option est utile lorsque vous gérez la validation à un niveau supérieur, par exemple dans un formulaire parent.

## Règles présentes par défaut

Le composant DatePicker intègre certaines règles de validation par défaut, sans que vous ayez besoin de les spécifier via `customRules` :

### Validation du champ requis

Lorsque la prop `required` est définie à `true`, le DatePicker effectue automatiquement une validation pour s'assurer qu'une date est sélectionnée. Si aucune date n'est sélectionnée, le message d'erreur "La date est requise." est affiché.

<Source
    dark code={`
<DatePicker
  v-model="date"
  required
/>
`}/>

### Validation du format de date

Le DatePicker vérifie automatiquement que la date saisie respecte le format spécifié par la prop `format` (par défaut `DD/MM/YYYY`). Cette validation est effectuée lorsque l'utilisateur saisit manuellement une date dans le champ de texte.

<Source
    dark code={`
<DatePicker
  v-model="date"
  format="MM/DD/YYYY" <!-- Format personnalisé -->
/>
`}/>

### Validation de la plage de dates

Lorsque `displayRange` est à `true`, le DatePicker valide automatiquement que la plage de dates est cohérente (date de début antérieure à date de fin) lorsque deux dates sont sélectionnées.

<Source
    dark code={`<DatePicker
  v-model="dateRange"
  display-range
/>
`}/>

## Interaction entre règles personnalisées et validations par défaut

Lorsque vous utilisez des règles personnalisées via `customRules` en combinaison avec des validations par défaut (comme `required`), il est important de comprendre comment ces règles interagissent :

### Ordre de priorité des validations

1. Les validations par défaut (comme `required`) sont exécutées en premier.
2. Si les validations par défaut réussissent, les règles personnalisées sont ensuite appliquées.
3. Les règles d'avertissement (`customWarningRules`) ne sont exécutées que si aucune erreur n'est détectée dans les étapes précédentes.

### Exemple d'interaction

<Source
    dark code={`<DatePicker
  v-model="date"
  required
  :custom-rules="[{ 
    type: 'notAfterToday', 
    options: { message: 'La date ne peut pas être après aujourd\'hui' } 
  }]"
/>
`}/>

Dans cet exemple :
- Si aucune date n'est sélectionnée, la validation `required` échoue et le message "La date est requise." s'affiche.
- Si une date est sélectionnée mais qu'elle est postérieure à aujourd'hui, la règle personnalisée `notAfterToday` échoue et son message d'erreur s'affiche.
- Si une date est sélectionnée et qu'elle est antérieure ou égale à aujourd'hui, toutes les validations réussissent.

<a href="/?path=/docs/guide-du-dev-guide-de-validation-des-formulaires--docs" className="action-link">Pour plus d'informations sur la validation, consultez le guide de validation des formulaires.</a>