@bobdivx/mf3d
TypeScript icon, indicating that this package has built-in type declarations

1.0.3 • Public • Published

Filament Manager

Gestion des traductions

Le projet utilise un système de traduction basé sur TypeScript pour gérer le contenu multilingue. Les traductions sont stockées dans le dossier src/i18n/locales/.

Structure des traductions

src/i18n/
├── locales/
│   ├── en/         # Dossier des traductions anglaises
│   │   ├── stats.ts
│   │   ├── filaments.ts
│   │   └── ...
│   ├── fr/         # Dossier des traductions françaises
│   │   ├── stats.ts
│   │   ├── filaments.ts
│   │   └── ...
│   ├── en.ts       # Fichier principal des traductions anglaises
│   └── fr.ts       # Fichier principal des traductions françaises
├── types.ts        # Types pour les traductions
├── config.ts       # Configuration et utilitaires de traduction
└── utils.ts        # Utilitaires (getLanguageFromURL, etc.)

Organisation des traductions

Les traductions sont organisées par modules fonctionnels. Par exemple, pour les statistiques :

// src/i18n/locales/fr/stats.ts
export const stats = {
  title: "Statistiques",
  description: "Statistiques des filaments",
  // Statistiques générales
  total_filaments: "Nombre total de filaments",
  total_weight: "Poids total",
  // Actions
  actions: {
    refresh: "Rafraîchir",
    print: "Imprimer",
  },
  // Sous-sections
  filaments_stats: {
    title: "Filaments",
    // ...
  },
  prints_stats: {
    title: "Impressions",
    // ...
  },
};

Procédure d'utilisation des traductions

1. Dans une page Astro

  1. Imports nécessaires :

    ---
    import Layout from '@/layouts/Layout.astro';
    import { getLangFromUrl, useTranslations } from '@/i18n/config';
    ---
  2. Récupération de la langue et utilisation des traductions :

    ---
    const lang = getLangFromUrl(Astro.url);
    const t = useTranslations(lang);
    ---
  3. Structure de la page :

    <Layout title={t('stats.title')} description={t('stats.description')} lang={lang}>
      <div>
        <h1>{t('stats.title')}</h1>
        <p>{t('stats.description')}</p>
      </div>
    </Layout>

2. Dans un composant Preact

  1. Import du hook :

    import { useTranslations } from "@/i18n/config";
  2. Utilisation dans le composant :

    interface Props {
      lang: Language;
    }
    
    export default function MonComposant({ lang }: Props) {
      const t = useTranslations(lang);
    
      return (
        <div>
          <h1>{t("stats.title")}</h1>
          <p>{t("stats.description")}</p>
        </div>
      );
    }

Ajout de nouvelles traductions

  1. Structure des fichiers de traduction :

    • Chaque module (ex: stats, filaments) a son propre fichier dans les dossiers en/ et fr/
    • Les fichiers principaux en.ts et fr.ts importent et agrègent tous les modules
    • Toujours ajouter les traductions dans les deux langues (FR et EN)
  2. Exemple d'ajout d'une nouvelle section :

    // Dans src/i18n/locales/fr/stats.ts
    export const stats = {
      // ... traductions existantes
      nouvelle_section: {
        title: "Titre de la section",
        description: "Description de la section",
        // ... autres traductions
      },
    };
    
    // Dans src/i18n/locales/en/stats.ts
    export const stats = {
      // ... existing translations
      nouvelle_section: {
        title: "Section title",
        description: "Section description",
        // ... other translations
      },
    };
  3. Bonnes pratiques :

    • Utiliser des clés descriptives et cohérentes
    • Organiser les traductions de manière hiérarchique
    • Maintenir la même structure dans toutes les langues
    • Vérifier que toutes les clés existent dans toutes les langues
    • Utiliser des valeurs appropriées pour chaque langue

Utilisation des traductions dans le code

  1. Accès simple :

    t("stats.title");
  2. Avec des variables :

    `${value} ${t("stats.unit")}`;
  3. Pour les actions :

    const actions = {
      label: t("stats.actions.refresh"),
      onClickId: "refresh-stats",
    };

Maintenance des traductions

  1. Vérification des clés manquantes :

    • S'assurer que chaque clé existe dans toutes les langues
    • Maintenir la même structure hiérarchique
  2. Mise à jour des traductions :

    • Modifier les fichiers de traduction correspondants
    • Tester l'affichage dans toutes les langues
    • Vérifier la cohérence des traductions
  3. Tests :

    • Vérifier l'affichage dans l'interface
    • Tester le changement de langue
    • Valider les traductions avec les utilisateurs

Design System

Page Layout

Chaque page principale suit une structure cohérente :

  1. Bandeau d'en-tête (Header Banner)

    • Dégradé de couleur personnalisable via les variables CSS
    • Titre principal et sous-titre
    • Actions principales
    • Classes : header-banner, header-banner-content, header-banner-title
  2. Sections de contenu

    • Cartes avec ombres et coins arrondis
    • Icônes dans des cercles avec couleurs pastels
    • Classes : section-card, section-card-title

Composants

  1. Icônes

    • Toujours affichées dans des cercles
    • Tailles standardisées :
      • Grande : section-icon (40x40px)
      • Petite : section-icon-sm (32x32px)
    • Couleurs pastels prédéfinies :
      • section-icon-blue
      • section-icon-purple
      • section-icon-green
      • section-icon-yellow
      • section-icon-amber
  2. Boutons

    • Style principal : header-banner-button
    • Avec icône : header-banner-button-icon

Thème et Personnalisation

Les couleurs du bandeau sont personnalisables via les variables CSS :

:root {
  --banner-from-color: theme("colors.blue.500");
  --banner-to-color: theme("colors.purple.600");
}

Pour le thème sombre :

[data-theme="dark"] {
  --banner-from-color: theme("colors.blue.600");
  --banner-to-color: theme("colors.purple.700");
}

Utilisation

Exemple de structure de page :

<div class="header-banner">
  <div class="header-banner-content">
    <h1 class="header-banner-title">Titre de la page</h1>
    <p class="header-banner-subtitle">Description</p>
  </div>
</div>

<div class="section-card">
  <h2 class="section-card-title">
    <div class="section-icon section-icon-blue">
      <Icon />
    </div>
    Titre de section
  </h2>
  <!-- Contenu -->
</div>

Gestion des types pour les traductions

  1. Types de base :

    • Les traductions retournent un type TranslationValue qui peut être soit une string soit une fonction retournant une string
    • Pour convertir une traduction en string, utilisez la fonction getTranslationString() :
    import { getTranslationString } from "@/lib/utils/translation";
    
    // Dans un composant
    const t = useTranslations(lang);
    const title = getTranslationString(t("page.title"));
  2. Utilisation dans les composants :

    • Pour les props qui attendent une string, utilisez toujours getTranslationString() :
    <Button disabled={isLoading}>
      {getTranslationString(t('common.save'))}
    </Button>
  3. Bonnes pratiques :

    • Utilisez getTranslationString() pour les props qui attendent une string
    • Pour les textes affichés directement dans le JSX, vous pouvez utiliser directement t()
    • Vérifiez les types TypeScript pour éviter les erreurs de compilation

Gestion des stocks de filaments

Le système de gestion des stocks de filaments permet d'ajouter et de retirer des bobines entières de filament, en tenant compte du poids défini pour chaque type de filament.

Structure du système

  1. Composants principaux :

    • SpoolManager : Interface utilisateur pour gérer le stock
    • TargetSpoolsManager : Interface pour définir le stock cible
    • FilamentHistory : Affichage de l'historique des modifications
  2. API :

    • /api/filaments/[id]/spool : Endpoint pour ajouter/retirer du stock
    • /api/filaments/[id]/target : Endpoint pour définir le stock cible

Fonctionnement du SpoolManager

Le composant SpoolManager affiche l'état actuel du stock et permet d'ajouter ou de retirer des bobines complètes.

<SpoolManager
  filamentId={filament.id}
  currentStock={remainingWeight}
  targetStock={targetTotalWeight}
  _lang={lang}
  client:load
/>

Propriétés importantes :

  • filamentId : Identifiant unique du filament
  • currentStock : Poids actuel restant en grammes
  • targetStock : Poids cible total en grammes
  • _lang : Langue courante pour les traductions

Caractéristiques :

  1. Affichage :

    • Poids en kilogrammes (pour plus de lisibilité)
    • Nombre de bobines actuelles et cibles
    • Pourcentage du stock par rapport à l'objectif
    • Radar visuel montrant la proportion du stock
  2. Actions :

    • Bouton pour ajouter une bobine entière
    • Bouton pour retirer une bobine entière
    • Validations pour empêcher le stock négatif

API de gestion du stock

L'API /api/filaments/[id]/spool est conçue pour gérer les ajouts et retraits de stock.

Requête :

// Exemple d'appel pour ajouter du stock
fetch(`/api/filaments/${filamentId}/spool`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ weight: 1000 }), // Poids positif pour ajouter
});

// Exemple d'appel pour retirer du stock
fetch(`/api/filaments/${filamentId}/spool`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ weight: -1000 }), // Poids négatif pour retirer
});

Fonctionnement interne :

  1. Récupération du contexte :

    • Poids actuel du filament (remaining_weight)
    • Poids d'une bobine individuelle (weight)
  2. Calcul du nouveau poids :

    • Addition du poids fourni au poids actuel
    • Validation que le résultat n'est pas négatif
  3. Mise à jour de la base de données :

    • Mise à jour du champ remaining_weight
    • Ajout d'une entrée dans l'historique avec l'opération et la quantité
  4. Réponse :

    {
      "success": true,
      "previousWeight": 1000,
      "newWeight": 2000,
      "spoolWeight": 1000,
      "difference": 1000,
      "totalSpools": 2
    }

Historique des modifications

Chaque modification de stock est enregistrée dans la table filament_history avec les informations suivantes :

  • filament_id : ID du filament concerné
  • operation : Type d'opération ('add' ou 'remove')
  • quantity : Quantité ajoutée ou retirée (toujours positive)
  • user_id : ID de l'utilisateur ayant effectué l'opération
  • created_at : Date et heure de l'opération

Bonnes pratiques

  1. Opérations par bobines entières :

    • Toujours ajouter ou retirer des bobines entières
    • Le poids d'une bobine est défini dans la base de données pour chaque filament
  2. Validation des données :

    • Vérifier que le stock ne devient pas négatif
    • Valider les entrées utilisateur
    • Utiliser des valeurs par défaut appropriées
  3. Affichage des informations :

    • Afficher les poids en kilogrammes (plus lisible)
    • Afficher également le nombre de bobines
    • Utiliser des indicateurs visuels (comme le radar de stock)
  4. Gestion des erreurs :

    • Afficher des messages d'erreur clairs
    • Utiliser le composant Toast pour les notifications
    • Logger les erreurs pour le débogage

Exemple complet

// Composant SpoolManager (version simplifiée)
function SpoolManager({ filamentId, currentStock, targetStock, _lang }) {
  const t = useTranslations(_lang);
  const handleUpdateStock = async (action) => {
    try {
      const weightChange = action === "add" ? spoolWeight : -spoolWeight;
      await fetch(`/api/filaments/${filamentId}/spool`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ weight: weightChange }),
      });
      // Notification et rafraîchissement
    } catch (error) {
      // Gestion des erreurs
    }
  };

  return (
    <div>
      {/* Affichage du stock */}
      <div>
        {currentStockKg} kg ({currentSpools} bobines)
      </div>

      {/* Boutons d'action */}
      <Button onClick={() => handleUpdateStock("add")}>
        Ajouter une bobine
      </Button>
      <Button onClick={() => handleUpdateStock("remove")}>
        Retirer une bobine
      </Button>
    </div>
  );
}

Authentification et Comptes de Test

Le système d'authentification utilise bcrypt pour le hachage sécurisé des mots de passe et des sessions basées sur des tokens.

Comptes de Test Disponibles

Deux comptes de test sont disponibles pour le développement :

  1. Compte Administrateur

  2. Compte Utilisateur Test

Processus d'Authentification

  1. Connexion

    • Les identifiants sont envoyés à /api/auth/login
    • Le serveur vérifie l'existence de l'utilisateur
    • Le mot de passe est vérifié avec bcrypt
    • Une session est créée avec un token unique
    • Un cookie sécurisé est défini avec le token
  2. Sécurité

    • Les mots de passe sont hachés avec bcrypt (10 rounds)
    • Les sessions expirent après 7 jours
    • Les cookies sont configurés avec :
      • HttpOnly
      • SameSite=Lax
      • Secure en production
      • Path=/
  3. Déconnexion

    • La session est supprimée de la base de données
    • Le cookie est expiré

Dépannage de l'Authentification

Si vous rencontrez des problèmes de connexion :

  1. Vérifiez les logs

    • Les logs détaillés sont disponibles dans la console du navigateur
    • Les logs serveur montrent le processus d'authentification
  2. Vérifiez les cookies

    • Le cookie turso-token doit être présent après la connexion
    • Les options du cookie doivent correspondre à la configuration
  3. Vérifiez la base de données

    • L'utilisateur doit exister dans la table auth_users
    • Le mot de passe doit être correctement haché
    • La session doit être créée dans la table sessions

Readme

Keywords

none

Package Sidebar

Install

npm i @bobdivx/mf3d

Weekly Downloads

2

Version

1.0.3

License

none

Unpacked Size

32.3 MB

Total Files

533

Last publish

Collaborators

  • bobdivx