Getting Started
Quick Start
Guide de développement rapide pour 2Krika
Quick Start
Ce guide vous aide à démarrer rapidement le développement sur le projet 2Krika.
Workflow de Développement
1. Créer une Branche
# Créer une nouvelle branche depuis dev
git checkout dev
git pull origin dev
git checkout -b feature/nom-de-votre-feature2. Démarrer le Serveur de Développement
# Depuis la racine du projet
pnpm dev
# Ou pour une app spécifique
cd apps/customers
pnpm dev3. Faire vos Modifications
Suivez les conventions de code du projet et testez vos modifications localement.
4. Commit et Push
git add .
git commit -m "feat: description de votre feature"
git push origin feature/nom-de-votre-feature5. Créer une Pull Request
Créez une PR vers la branche dev avec une description claire de vos changements.
Structure d'une Feature
Exemple: Ajouter une Nouvelle Page
Pour l'app customers avec routing internationalisé:
import { useTranslations } from 'next-intl';
export default function NouvellePage() {
const t = useTranslations('NouvellePage');
return (
<div>
<h1>{t('title')}</h1>
<p>{t('description')}</p>
</div>
);
}Ajouter les traductions:
{
"NouvellePage": {
"title": "Nouvelle Page",
"description": "Description de la page"
}
}{
"NouvellePage": {
"title": "New Page",
"description": "Page description"
}
}Exemple: Créer un Composant Réutilisable
import { Card, Avatar, Text } from '@mantine/core';
import { User } from '@/models/user';
interface UserCardProps {
user: User;
onClick?: () => void;
}
export function UserCard({ user, onClick }: UserCardProps) {
return (
<Card onClick={onClick} className="cursor-pointer hover:shadow-lg">
<Avatar src={user.avatar} size="lg" />
<Text size="lg" fw={600}>{user.name}</Text>
<Text size="sm" c="dimmed">{user.email}</Text>
</Card>
);
}Exemple: Créer un Hook Personnalisé
import { useQuery } from '@tanstack/react-query';
import { userService } from '@/services/userService';
export function useUser(userId: string) {
return useQuery({
queryKey: ['user', userId],
queryFn: () => userService.getUser(userId),
enabled: !!userId,
});
}Exemple: Créer un Service API
import api from '@/config/api';
import { User } from '@/models/user';
export const userService = {
getUser: async (userId: string): Promise<User> => {
const { data } = await api.get(`/users/${userId}`);
return data;
},
updateUser: async (userId: string, userData: Partial<User>): Promise<User> => {
const { data } = await api.put(`/users/${userId}`, userData);
return data;
},
};Travailler avec React Query
Récupérer des Données
'use client';
import { useQuery } from '@tanstack/react-query';
import { serviceService } from '@/services/serviceService';
export function ServicesList() {
const { data, isLoading, error } = useQuery({
queryKey: ['services'],
queryFn: serviceService.getAll,
});
if (isLoading) return <div>Chargement...</div>;
if (error) return <div>Erreur: {error.message}</div>;
return (
<div>
{data?.map(service => (
<ServiceCard key={service.id} service={service} />
))}
</div>
);
}Mutations
'use client';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { serviceService } from '@/services/serviceService';
export function CreateServiceForm() {
const queryClient = useQueryClient();
const mutation = useMutation({
mutationFn: serviceService.create,
onSuccess: () => {
// Invalider et refetch
queryClient.invalidateQueries({ queryKey: ['services'] });
},
});
const handleSubmit = (data: CreateServiceData) => {
mutation.mutate(data);
};
return (
<form onSubmit={handleSubmit}>
{/* Form fields */}
</form>
);
}Travailler avec Zustand
Créer un Store
import { create } from 'zustand';
import { User } from '@/models/user';
interface AuthState {
user: User | null;
token: string | null;
setUser: (user: User) => void;
setToken: (token: string) => void;
logout: () => void;
}
export const useAuthStore = create<AuthState>((set) => ({
user: null,
token: null,
setUser: (user) => set({ user }),
setToken: (token) => set({ token }),
logout: () => set({ user: null, token: null }),
}));Utiliser le Store
'use client';
import { useAuthStore } from '@/stores/authStore';
export function UserProfile() {
const user = useAuthStore((state) => state.user);
const logout = useAuthStore((state) => state.logout);
if (!user) return null;
return (
<div>
<h2>{user.name}</h2>
<button onClick={logout}>Se déconnecter</button>
</div>
);
}Styling avec Tailwind
Classes Utilitaires
<div className="flex items-center justify-between p-4 bg-white rounded-lg shadow-md">
<h2 className="text-2xl font-bold text-gray-900">Titre</h2>
<button className="px-4 py-2 text-white bg-blue-600 rounded hover:bg-blue-700">
Action
</button>
</div>Responsive Design
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{/* Cards */}
</div>Composants Mantine
Utilisation de Base
import { Button, TextInput, Modal } from '@mantine/core';
export function MyForm() {
return (
<>
<TextInput
label="Email"
placeholder="votre@email.com"
required
/>
<Button type="submit">Envoyer</Button>
</>
);
}Formulaires avec Mantine
'use client';
import { useForm } from '@mantine/form';
import { TextInput, Button } from '@mantine/core';
export function ContactForm() {
const form = useForm({
initialValues: {
email: '',
name: '',
},
validate: {
email: (value) => (/^\S+@\S+$/.test(value) ? null : 'Email invalide'),
},
});
return (
<form onSubmit={form.onSubmit(console.log)}>
<TextInput
label="Nom"
{...form.getInputProps('name')}
/>
<TextInput
label="Email"
{...form.getInputProps('email')}
/>
<Button type="submit">Envoyer</Button>
</form>
);
}Socket.io pour Real-time
Connexion Socket
'use client';
import { useEffect, useState } from 'react';
import { io, Socket } from 'socket.io-client';
export function useSocket() {
const [socket, setSocket] = useState<Socket | null>(null);
useEffect(() => {
const socketInstance = io(process.env.NEXT_PUBLIC_SOCKET_URL!);
setSocket(socketInstance);
return () => {
socketInstance.disconnect();
};
}, []);
return socket;
}Écouter les Événements
'use client';
import { useEffect } from 'react';
import { useSocket } from '@/hooks/useSocket';
export function ChatComponent() {
const socket = useSocket();
useEffect(() => {
if (!socket) return;
socket.on('message', (data) => {
console.log('Nouveau message:', data);
});
return () => {
socket.off('message');
};
}, [socket]);
return <div>Chat Component</div>;
}Tests
Tester un Composant
import { render, screen } from '@testing-library/react';
import { UserCard } from './UserCard';
describe('UserCard', () => {
it('affiche le nom de l\'utilisateur', () => {
const user = { id: '1', name: 'John Doe', email: 'john@example.com' };
render(<UserCard user={user} />);
expect(screen.getByText('John Doe')).toBeInTheDocument();
});
});Commandes Utiles
# Vérifier les types
pnpm check-types
# Linter le code
pnpm lint
# Formater le code
pnpm format
# Build pour la production
pnpm build
# Nettoyer les caches
rm -rf .next node_modules
pnpm installDebugging
Logs dans le Navigateur
console.log('Debug:', data);
console.error('Error:', error);React DevTools
Installez l'extension React DevTools pour Chrome/Firefox pour inspecter les composants.
Network Tab
Utilisez l'onglet Network dans les DevTools pour inspecter les requêtes API.