188 lines
9.1 KiB
PHP
188 lines
9.1 KiB
PHP
<?php
|
|
$pageTitle = 'Contact';
|
|
$pageDescription = 'Contactez-moi pour discuter de votre projet web ou d\'une opportunité professionnelle.';
|
|
$currentPage = 'contact';
|
|
|
|
$csrfToken = generateCsrfToken();
|
|
|
|
include_template('header', compact('pageTitle', 'pageDescription'));
|
|
include_template('navbar', compact('currentPage'));
|
|
?>
|
|
|
|
<main>
|
|
<section class="section">
|
|
<div class="container-content">
|
|
<div class="max-w-2xl mx-auto">
|
|
<div class="text-center mb-12">
|
|
<h1 class="text-display mb-4">Me Contacter</h1>
|
|
<p class="text-xl text-text-secondary">
|
|
Une question, un projet ? Parlons-en !
|
|
</p>
|
|
</div>
|
|
|
|
<form
|
|
id="contact-form"
|
|
method="POST"
|
|
action="/api/contact.php"
|
|
class="space-y-6"
|
|
>
|
|
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($csrfToken) ?>">
|
|
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 gap-6">
|
|
<div>
|
|
<label for="nom" class="label">Nom <span class="text-primary">*</span></label>
|
|
<input
|
|
type="text"
|
|
id="nom"
|
|
name="nom"
|
|
class="input"
|
|
required
|
|
maxlength="100"
|
|
autocomplete="family-name"
|
|
placeholder="Dupont"
|
|
>
|
|
<p class="error-message hidden" data-error="nom"></p>
|
|
</div>
|
|
|
|
<div>
|
|
<label for="prenom" class="label">Prénom <span class="text-primary">*</span></label>
|
|
<input
|
|
type="text"
|
|
id="prenom"
|
|
name="prenom"
|
|
class="input"
|
|
required
|
|
maxlength="100"
|
|
autocomplete="given-name"
|
|
placeholder="Marie"
|
|
>
|
|
<p class="error-message hidden" data-error="prenom"></p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 gap-6">
|
|
<div>
|
|
<label for="email" class="label">Email <span class="text-primary">*</span></label>
|
|
<input
|
|
type="email"
|
|
id="email"
|
|
name="email"
|
|
class="input"
|
|
required
|
|
maxlength="255"
|
|
autocomplete="email"
|
|
placeholder="marie.dupont@example.com"
|
|
>
|
|
<p class="error-message hidden" data-error="email"></p>
|
|
</div>
|
|
|
|
<div>
|
|
<label for="entreprise" class="label">Entreprise <span class="text-text-muted">(optionnel)</span></label>
|
|
<input
|
|
type="text"
|
|
id="entreprise"
|
|
name="entreprise"
|
|
class="input"
|
|
maxlength="200"
|
|
autocomplete="organization"
|
|
placeholder="Nom de votre entreprise"
|
|
>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label for="categorie" class="label">Catégorie <span class="text-primary">*</span></label>
|
|
<select id="categorie" name="categorie" class="input" required>
|
|
<option value="" disabled selected>Sélectionnez une catégorie...</option>
|
|
<option value="projet">Je souhaite parler de mon projet</option>
|
|
<option value="poste">Je souhaite vous proposer un poste</option>
|
|
<option value="autre">Autre</option>
|
|
</select>
|
|
<p class="error-message hidden" data-error="categorie"></p>
|
|
</div>
|
|
|
|
<div>
|
|
<label for="objet" class="label">Objet <span class="text-primary">*</span></label>
|
|
<input
|
|
type="text"
|
|
id="objet"
|
|
name="objet"
|
|
class="input"
|
|
required
|
|
maxlength="200"
|
|
placeholder="Résumez votre demande en quelques mots"
|
|
>
|
|
<p class="error-message hidden" data-error="objet"></p>
|
|
</div>
|
|
|
|
<div>
|
|
<label for="message" class="label">Message <span class="text-primary">*</span></label>
|
|
<textarea
|
|
id="message"
|
|
name="message"
|
|
class="textarea"
|
|
required
|
|
maxlength="5000"
|
|
rows="6"
|
|
placeholder="Décrivez votre projet ou votre demande..."
|
|
></textarea>
|
|
<p class="error-message hidden" data-error="message"></p>
|
|
<p class="text-xs text-text-muted mt-2">
|
|
<span id="message-count">0</span> / 5000 caractères
|
|
</p>
|
|
</div>
|
|
|
|
<div class="flex flex-col sm:flex-row gap-4 pt-4">
|
|
<button type="submit" id="submit-btn" class="btn-primary flex-1 justify-center">
|
|
<span id="submit-text">Envoyer le message</span>
|
|
<span id="submit-loading" class="hidden">
|
|
<svg class="animate-spin w-5 h-5" fill="none" viewBox="0 0 24 24">
|
|
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
|
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path>
|
|
</svg>
|
|
Envoi en cours...
|
|
</span>
|
|
</button>
|
|
<button type="button" id="clear-form-btn" class="btn-ghost">
|
|
Effacer le formulaire
|
|
</button>
|
|
</div>
|
|
</form>
|
|
|
|
<div id="success-message" class="hidden mt-8 p-6 bg-success/10 border border-success/30 rounded-lg text-center">
|
|
<svg class="w-12 h-12 text-success mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
|
</svg>
|
|
<h3 class="text-lg font-semibold text-text-primary mb-2">Message envoyé avec succès !</h3>
|
|
<p class="text-text-secondary mb-4">
|
|
Merci pour votre message. Je vous répondrai dans les meilleurs délais.
|
|
</p>
|
|
<p class="text-sm text-text-muted">
|
|
Si vous ne recevez pas de réponse sous 48h, pensez à vérifier vos spams.
|
|
</p>
|
|
</div>
|
|
|
|
<div id="error-message" class="hidden mt-8 p-6 bg-error/10 border border-error/30 rounded-lg">
|
|
<div class="flex items-start gap-4">
|
|
<svg class="w-6 h-6 text-error flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
|
</svg>
|
|
<div>
|
|
<h3 class="font-semibold text-error mb-1">Erreur</h3>
|
|
<p class="text-text-secondary" id="error-text"></p>
|
|
<p class="text-sm text-text-muted mt-2">
|
|
Vos données ont été conservées. Vous pouvez réessayer.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
|
|
<script src="/assets/js/state.js" defer></script>
|
|
<script src="/assets/js/contact-form.js" defer></script>
|
|
|
|
<?php include_template('footer'); ?>
|