fix: telegram link
This commit is contained in:
@@ -1,307 +1,433 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from "react";
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from "react-router-dom";
|
||||||
import Navbar from '../../components/Navbar';
|
import Navbar from "../../components/Navbar";
|
||||||
import { isUserAuthenticated, extractUsernameFromToken, getMyProfile, updateMyProfile, getTelegramStatus, generateTelegramLinkToken, unlinkTelegram } from '../../api/api';
|
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
||||||
import {
|
import {
|
||||||
faUser, faMapMarkerAlt, faPhone, faCommentDots,
|
isUserAuthenticated,
|
||||||
faSave, faCheckCircle, faExclamationTriangle, faPaperPlane, faUnlink, faTimes, faLock,
|
extractUsernameFromToken,
|
||||||
} from '@fortawesome/free-solid-svg-icons';
|
getMyProfile,
|
||||||
import './ProfilePage.css';
|
updateMyProfile,
|
||||||
|
getTelegramStatus,
|
||||||
|
generateTelegramLinkToken,
|
||||||
|
unlinkTelegram,
|
||||||
|
} from "../../api/api";
|
||||||
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
import {
|
||||||
|
faUser,
|
||||||
|
faMapMarkerAlt,
|
||||||
|
faPhone,
|
||||||
|
faCommentDots,
|
||||||
|
faSave,
|
||||||
|
faCheckCircle,
|
||||||
|
faExclamationTriangle,
|
||||||
|
faPaperPlane,
|
||||||
|
faUnlink,
|
||||||
|
faTimes,
|
||||||
|
faLock,
|
||||||
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
|
import "./ProfilePage.css";
|
||||||
|
|
||||||
const STORAGE_ADDRESS = 'profile_default_address';
|
const STORAGE_ADDRESS = "profile_default_address";
|
||||||
const STORAGE_PHONE = 'profile_default_phone';
|
const STORAGE_PHONE = "profile_default_phone";
|
||||||
const STORAGE_SIGNAL = 'profile_signal_pseudo';
|
const STORAGE_SIGNAL = "profile_signal_pseudo";
|
||||||
|
|
||||||
export default function ProfilePage() {
|
export default function ProfilePage() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
// Données compte (backend)
|
// Données compte (backend)
|
||||||
const [nom, setNom] = useState('');
|
const [nom, setNom] = useState("");
|
||||||
const [prenom, setPrenom] = useState('');
|
const [prenom, setPrenom] = useState("");
|
||||||
const [telephone, setTelephone] = useState('');
|
const [telephone, setTelephone] = useState("");
|
||||||
const [loadingProfile, setLoadingProfile] = useState(true);
|
const [loadingProfile, setLoadingProfile] = useState(true);
|
||||||
|
|
||||||
// Données locales (localStorage)
|
// Données locales (localStorage)
|
||||||
const [defaultAddress, setDefaultAddress] = useState(() => localStorage.getItem(STORAGE_ADDRESS) ?? '');
|
const [defaultAddress, setDefaultAddress] = useState(
|
||||||
const [defaultPhone, setDefaultPhone] = useState(() => localStorage.getItem(STORAGE_PHONE) ?? '');
|
() => localStorage.getItem(STORAGE_ADDRESS) ?? "",
|
||||||
const [signalPseudo, setSignalPseudo] = useState(() => localStorage.getItem(STORAGE_SIGNAL) ?? '');
|
);
|
||||||
|
const [defaultPhone, setDefaultPhone] = useState(
|
||||||
// Feedback
|
() => localStorage.getItem(STORAGE_PHONE) ?? "",
|
||||||
const [savingContact, setSavingContact] = useState(false);
|
);
|
||||||
const [successMsg, setSuccessMsg] = useState('');
|
const [signalPseudo, setSignalPseudo] = useState(
|
||||||
const [errorMsg, setErrorMsg] = useState('');
|
() => localStorage.getItem(STORAGE_SIGNAL) ?? "",
|
||||||
|
|
||||||
// Telegram
|
|
||||||
const [tgLinked, setTgLinked] = useState(false);
|
|
||||||
const [tgEnabled, setTgEnabled] = useState(false);
|
|
||||||
const [tgLoading, setTgLoading] = useState(false);
|
|
||||||
|
|
||||||
// Modal confirmation infos par défaut
|
|
||||||
const [showSaveModal, setShowSaveModal] = useState(false);
|
|
||||||
|
|
||||||
const username = extractUsernameFromToken() ?? '';
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!isUserAuthenticated()) {
|
|
||||||
navigate('/login/client', { replace: true });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Statut Telegram
|
|
||||||
getTelegramStatus().then((s) => { setTgLinked(s.linked); setTgEnabled(s.enabled); });
|
|
||||||
|
|
||||||
// Charger depuis backend
|
|
||||||
getMyProfile().then((res) => {
|
|
||||||
if (res.success && res.client) {
|
|
||||||
setNom(res.client.nom ?? '');
|
|
||||||
setPrenom(res.client.prenom ?? '');
|
|
||||||
setTelephone(res.client.telephone ?? '');
|
|
||||||
// Initialiser le téléphone par défaut si pas encore défini
|
|
||||||
if (!localStorage.getItem(STORAGE_PHONE) && res.client.telephone) {
|
|
||||||
setDefaultPhone(res.client.telephone);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setLoadingProfile(false);
|
|
||||||
});
|
|
||||||
}, [navigate]);
|
|
||||||
|
|
||||||
const showSuccess = (msg: string) => {
|
|
||||||
setSuccessMsg(msg);
|
|
||||||
setErrorMsg('');
|
|
||||||
setTimeout(() => setSuccessMsg(''), 3000);
|
|
||||||
};
|
|
||||||
const showError = (msg: string) => {
|
|
||||||
setErrorMsg(msg);
|
|
||||||
setSuccessMsg('');
|
|
||||||
setTimeout(() => setErrorMsg(''), 4000);
|
|
||||||
};
|
|
||||||
|
|
||||||
const saveLocal = () => {
|
|
||||||
localStorage.setItem(STORAGE_ADDRESS, defaultAddress.trim());
|
|
||||||
localStorage.setItem(STORAGE_PHONE, defaultPhone.trim());
|
|
||||||
localStorage.setItem(STORAGE_SIGNAL, signalPseudo.trim());
|
|
||||||
setShowSaveModal(false);
|
|
||||||
showSuccess('Informations par défaut enregistrées');
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleLinkTelegram = async () => {
|
|
||||||
setTgLoading(true);
|
|
||||||
const res = await generateTelegramLinkToken();
|
|
||||||
setTgLoading(false);
|
|
||||||
if (res.error || !res.link_url) {
|
|
||||||
showError(res.error || 'Service Telegram non disponible');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
window.open(res.link_url, '_blank');
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleUnlinkTelegram = async () => {
|
|
||||||
if (!window.confirm('Délier votre compte Telegram ? Vous ne recevrez plus de notifications.')) return;
|
|
||||||
await unlinkTelegram();
|
|
||||||
setTgLinked(false);
|
|
||||||
showSuccess('Compte Telegram délié');
|
|
||||||
};
|
|
||||||
|
|
||||||
const saveContact = async () => {
|
|
||||||
setSavingContact(true);
|
|
||||||
const res = await updateMyProfile({ nom: nom.trim(), prenom: prenom.trim(), telephone: telephone.trim() });
|
|
||||||
setSavingContact(false);
|
|
||||||
if (res.success) {
|
|
||||||
showSuccess('Profil mis à jour');
|
|
||||||
} else {
|
|
||||||
showError(res.message ?? 'Erreur lors de la mise à jour');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (loadingProfile) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Navbar />
|
|
||||||
<div className="profile-container">
|
|
||||||
<div className="profile-loading"><div className="spinner" /></div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
// Feedback
|
||||||
<>
|
const [savingContact, setSavingContact] = useState(false);
|
||||||
<Navbar />
|
const [successMsg, setSuccessMsg] = useState("");
|
||||||
<div className="profile-container">
|
const [errorMsg, setErrorMsg] = useState("");
|
||||||
<div className="profile-header">
|
|
||||||
<div className="profile-avatar">
|
|
||||||
<FontAwesomeIcon icon={faUser} />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h1 className="profile-title">Mon Profil</h1>
|
|
||||||
<p className="profile-username">@{username}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{successMsg && (
|
// Telegram
|
||||||
<div className="profile-alert profile-alert--success">
|
const [tgLinked, setTgLinked] = useState(false);
|
||||||
<FontAwesomeIcon icon={faCheckCircle} /> {successMsg}
|
const [tgEnabled, setTgEnabled] = useState(false);
|
||||||
</div>
|
const [tgLoading, setTgLoading] = useState(false);
|
||||||
)}
|
|
||||||
{errorMsg && (
|
|
||||||
<div className="profile-alert profile-alert--error">
|
|
||||||
<FontAwesomeIcon icon={faExclamationTriangle} /> {errorMsg}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Section compte */}
|
// Modal confirmation infos par défaut
|
||||||
<div className="profile-card">
|
const [showSaveModal, setShowSaveModal] = useState(false);
|
||||||
<h2 className="profile-card-title">
|
|
||||||
<FontAwesomeIcon icon={faUser} className="profile-card-icon" />
|
const username = extractUsernameFromToken() ?? "";
|
||||||
Mon compte
|
|
||||||
</h2>
|
useEffect(() => {
|
||||||
<div className="profile-fields">
|
if (!isUserAuthenticated()) {
|
||||||
<div className="profile-row">
|
navigate("/login/client", { replace: true });
|
||||||
<div className="profile-group">
|
return;
|
||||||
<label>Prénom</label>
|
}
|
||||||
<input
|
// Statut Telegram
|
||||||
type="text"
|
getTelegramStatus().then((s) => {
|
||||||
value={prenom}
|
setTgLinked(s.linked);
|
||||||
onChange={(e) => setPrenom(e.target.value)}
|
setTgEnabled(s.enabled);
|
||||||
placeholder="Votre prénom"
|
});
|
||||||
/>
|
|
||||||
</div>
|
// Charger depuis backend
|
||||||
<div className="profile-group">
|
getMyProfile().then((res) => {
|
||||||
<label>Nom</label>
|
if (res.success && res.client) {
|
||||||
<input
|
setNom(res.client.nom ?? "");
|
||||||
type="text"
|
setPrenom(res.client.prenom ?? "");
|
||||||
value={nom}
|
setTelephone(res.client.telephone ?? "");
|
||||||
onChange={(e) => setNom(e.target.value)}
|
// Initialiser le téléphone par défaut si pas encore défini
|
||||||
placeholder="Votre nom"
|
if (
|
||||||
/>
|
!localStorage.getItem(STORAGE_PHONE) &&
|
||||||
</div>
|
res.client.telephone
|
||||||
|
) {
|
||||||
|
setDefaultPhone(res.client.telephone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setLoadingProfile(false);
|
||||||
|
});
|
||||||
|
}, [navigate]);
|
||||||
|
|
||||||
|
const showSuccess = (msg: string) => {
|
||||||
|
setSuccessMsg(msg);
|
||||||
|
setErrorMsg("");
|
||||||
|
setTimeout(() => setSuccessMsg(""), 3000);
|
||||||
|
};
|
||||||
|
const showError = (msg: string) => {
|
||||||
|
setErrorMsg(msg);
|
||||||
|
setSuccessMsg("");
|
||||||
|
setTimeout(() => setErrorMsg(""), 4000);
|
||||||
|
};
|
||||||
|
|
||||||
|
const saveLocal = () => {
|
||||||
|
localStorage.setItem(STORAGE_ADDRESS, defaultAddress.trim());
|
||||||
|
localStorage.setItem(STORAGE_PHONE, defaultPhone.trim());
|
||||||
|
localStorage.setItem(STORAGE_SIGNAL, signalPseudo.trim());
|
||||||
|
setShowSaveModal(false);
|
||||||
|
showSuccess("Informations par défaut enregistrées");
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleLinkTelegram = async () => {
|
||||||
|
setTgLoading(true);
|
||||||
|
|
||||||
|
// ✅ Ouvrir AVANT le await
|
||||||
|
const newWindow = window.open("", "_blank");
|
||||||
|
|
||||||
|
const res = await generateTelegramLinkToken();
|
||||||
|
setTgLoading(false);
|
||||||
|
|
||||||
|
if (res.error || !res.link_url) {
|
||||||
|
newWindow?.close();
|
||||||
|
showError(res.error || "Service Telegram non disponible");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
|
||||||
|
|
||||||
|
if (isIOS) {
|
||||||
|
const botUsername = res.link_url.split("t.me/")[1]?.split("?")[0];
|
||||||
|
const token = new URL(res.link_url).searchParams.get("start");
|
||||||
|
newWindow!.location.href = `tg://resolve?domain=${botUsername}&start=${token}`;
|
||||||
|
setTimeout(() => {
|
||||||
|
newWindow!.location.href = res.link_url!;
|
||||||
|
}, 1500);
|
||||||
|
} else {
|
||||||
|
newWindow!.location.href = res.link_url;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleUnlinkTelegram = async () => {
|
||||||
|
if (
|
||||||
|
!window.confirm(
|
||||||
|
"Délier votre compte Telegram ? Vous ne recevrez plus de notifications.",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
await unlinkTelegram();
|
||||||
|
setTgLinked(false);
|
||||||
|
showSuccess("Compte Telegram délié");
|
||||||
|
};
|
||||||
|
|
||||||
|
const saveContact = async () => {
|
||||||
|
setSavingContact(true);
|
||||||
|
const res = await updateMyProfile({
|
||||||
|
nom: nom.trim(),
|
||||||
|
prenom: prenom.trim(),
|
||||||
|
telephone: telephone.trim(),
|
||||||
|
});
|
||||||
|
setSavingContact(false);
|
||||||
|
if (res.success) {
|
||||||
|
showSuccess("Profil mis à jour");
|
||||||
|
} else {
|
||||||
|
showError(res.message ?? "Erreur lors de la mise à jour");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (loadingProfile) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Navbar />
|
||||||
|
<div className="profile-container">
|
||||||
|
<div className="profile-loading">
|
||||||
|
<div className="spinner" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Navbar />
|
||||||
|
<div className="profile-container">
|
||||||
|
<div className="profile-header">
|
||||||
|
<div className="profile-avatar">
|
||||||
|
<FontAwesomeIcon icon={faUser} />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1 className="profile-title">Mon Profil</h1>
|
||||||
|
<p className="profile-username">@{username}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{successMsg && (
|
||||||
|
<div className="profile-alert profile-alert--success">
|
||||||
|
<FontAwesomeIcon icon={faCheckCircle} /> {successMsg}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{errorMsg && (
|
||||||
|
<div className="profile-alert profile-alert--error">
|
||||||
|
<FontAwesomeIcon icon={faExclamationTriangle} />{" "}
|
||||||
|
{errorMsg}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Section compte */}
|
||||||
|
<div className="profile-card">
|
||||||
|
<h2 className="profile-card-title">
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faUser}
|
||||||
|
className="profile-card-icon"
|
||||||
|
/>
|
||||||
|
Mon compte
|
||||||
|
</h2>
|
||||||
|
<div className="profile-fields">
|
||||||
|
<div className="profile-row">
|
||||||
|
<div className="profile-group">
|
||||||
|
<label>Prénom</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={prenom}
|
||||||
|
onChange={(e) => setPrenom(e.target.value)}
|
||||||
|
placeholder="Votre prénom"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="profile-group">
|
||||||
|
<label>Nom</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={nom}
|
||||||
|
onChange={(e) => setNom(e.target.value)}
|
||||||
|
placeholder="Votre nom"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="profile-group">
|
||||||
|
<label>Téléphone (compte)</label>
|
||||||
|
<input
|
||||||
|
type="tel"
|
||||||
|
value={telephone}
|
||||||
|
onChange={(e) => setTelephone(e.target.value)}
|
||||||
|
placeholder="+33 6 12 34 56 78"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
className="profile-btn"
|
||||||
|
onClick={saveContact}
|
||||||
|
disabled={savingContact}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faSave} />
|
||||||
|
{savingContact
|
||||||
|
? " Enregistrement..."
|
||||||
|
: " Enregistrer le compte"}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="profile-btn profile-btn--secondary"
|
||||||
|
onClick={() => navigate("/user/change-password")}
|
||||||
|
style={{ marginTop: "0.6rem" }}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faLock} /> Changer le mot de
|
||||||
|
passe
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Section adresse par défaut */}
|
||||||
|
<div className="profile-card">
|
||||||
|
<h2 className="profile-card-title">
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faMapMarkerAlt}
|
||||||
|
className="profile-card-icon profile-card-icon--address"
|
||||||
|
/>
|
||||||
|
Adresse par défaut
|
||||||
|
</h2>
|
||||||
|
<p className="profile-hint">
|
||||||
|
Sera pré-remplie dans le formulaire de commande. Vous
|
||||||
|
pourrez la modifier si vous n'êtes pas à cette adresse.
|
||||||
|
</p>
|
||||||
|
<div className="profile-group">
|
||||||
|
<label>Adresse</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={defaultAddress}
|
||||||
|
onChange={(e) => setDefaultAddress(e.target.value)}
|
||||||
|
placeholder="Numéro, rue, ville, code postal"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Section contact commande */}
|
||||||
|
<div className="profile-card">
|
||||||
|
<h2 className="profile-card-title">
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faPhone}
|
||||||
|
className="profile-card-icon profile-card-icon--phone"
|
||||||
|
/>
|
||||||
|
Contact livraison
|
||||||
|
</h2>
|
||||||
|
<p className="profile-hint">
|
||||||
|
Numéro utilisé par le livreur lors de la livraison. Peut
|
||||||
|
être différent du numéro de votre compte.
|
||||||
|
</p>
|
||||||
|
<div className="profile-group">
|
||||||
|
<label>Téléphone par défaut</label>
|
||||||
|
<input
|
||||||
|
type="tel"
|
||||||
|
value={defaultPhone}
|
||||||
|
onChange={(e) => setDefaultPhone(e.target.value)}
|
||||||
|
placeholder="+33 6 12 34 56 78"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="profile-group"
|
||||||
|
style={{ marginTop: "1rem" }}
|
||||||
|
>
|
||||||
|
<label>
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faCommentDots}
|
||||||
|
style={{ marginRight: "0.4rem" }}
|
||||||
|
/>
|
||||||
|
Pseudo Signal (optionnel)
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={signalPseudo}
|
||||||
|
onChange={(e) => setSignalPseudo(e.target.value)}
|
||||||
|
placeholder="@votre.pseudo.signal"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
className="profile-btn profile-btn--secondary"
|
||||||
|
onClick={() => setShowSaveModal(true)}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faSave} /> Enregistrer les infos
|
||||||
|
par défaut
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{/* Section Telegram */}
|
||||||
|
{tgEnabled && (
|
||||||
|
<div className="profile-card">
|
||||||
|
<h2 className="profile-card-title">
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faPaperPlane}
|
||||||
|
className="profile-card-icon profile-card-icon--telegram"
|
||||||
|
/>
|
||||||
|
Notifications Telegram
|
||||||
|
</h2>
|
||||||
|
<p className="profile-hint">
|
||||||
|
Recevez vos notifications sur Telegram, même quand
|
||||||
|
le site est fermé.
|
||||||
|
</p>
|
||||||
|
{tgLinked ? (
|
||||||
|
<div className="profile-telegram-linked">
|
||||||
|
<span className="profile-telegram-status">
|
||||||
|
<FontAwesomeIcon icon={faCheckCircle} />{" "}
|
||||||
|
Compte Telegram lié
|
||||||
|
</span>
|
||||||
|
<button
|
||||||
|
className="profile-btn profile-btn--danger"
|
||||||
|
onClick={handleUnlinkTelegram}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faUnlink} /> Délier
|
||||||
|
Telegram
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<button
|
||||||
|
className="profile-btn profile-btn--telegram"
|
||||||
|
onClick={handleLinkTelegram}
|
||||||
|
disabled={tgLoading}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faPaperPlane} />
|
||||||
|
{tgLoading
|
||||||
|
? " Génération du lien..."
|
||||||
|
: " Lier mon compte Telegram"}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="profile-group">
|
|
||||||
<label>Téléphone (compte)</label>
|
|
||||||
<input
|
|
||||||
type="tel"
|
|
||||||
value={telephone}
|
|
||||||
onChange={(e) => setTelephone(e.target.value)}
|
|
||||||
placeholder="+33 6 12 34 56 78"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button className="profile-btn" onClick={saveContact} disabled={savingContact}>
|
|
||||||
<FontAwesomeIcon icon={faSave} />
|
|
||||||
{savingContact ? ' Enregistrement...' : ' Enregistrer le compte'}
|
|
||||||
</button>
|
|
||||||
<button className="profile-btn profile-btn--secondary" onClick={() => navigate('/user/change-password')} style={{ marginTop: '0.6rem' }}>
|
|
||||||
<FontAwesomeIcon icon={faLock} /> Changer le mot de passe
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Section adresse par défaut */}
|
{showSaveModal && (
|
||||||
<div className="profile-card">
|
<div
|
||||||
<h2 className="profile-card-title">
|
className="profile-modal-overlay"
|
||||||
<FontAwesomeIcon icon={faMapMarkerAlt} className="profile-card-icon profile-card-icon--address" />
|
onClick={() => setShowSaveModal(false)}
|
||||||
Adresse par défaut
|
>
|
||||||
</h2>
|
<div
|
||||||
<p className="profile-hint">
|
className="profile-modal"
|
||||||
Sera pré-remplie dans le formulaire de commande. Vous pourrez la modifier si vous n'êtes pas à cette adresse.
|
onClick={(e) => e.stopPropagation()}
|
||||||
</p>
|
>
|
||||||
<div className="profile-group">
|
<button
|
||||||
<label>Adresse</label>
|
className="profile-modal-close"
|
||||||
<input
|
onClick={() => setShowSaveModal(false)}
|
||||||
type="text"
|
>
|
||||||
value={defaultAddress}
|
<FontAwesomeIcon icon={faTimes} />
|
||||||
onChange={(e) => setDefaultAddress(e.target.value)}
|
</button>
|
||||||
placeholder="Numéro, rue, ville, code postal"
|
<div className="profile-modal-icon">
|
||||||
/>
|
<FontAwesomeIcon icon={faSave} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<h3 className="profile-modal-title">
|
||||||
|
Enregistrer les infos par défaut ?
|
||||||
{/* Section contact commande */}
|
</h3>
|
||||||
<div className="profile-card">
|
<p className="profile-modal-body">
|
||||||
<h2 className="profile-card-title">
|
Adresse, téléphone de livraison et pseudo Signal
|
||||||
<FontAwesomeIcon icon={faPhone} className="profile-card-icon profile-card-icon--phone" />
|
seront sauvegardés localement et pré-remplis lors de
|
||||||
Contact livraison
|
vos prochaines commandes.
|
||||||
</h2>
|
</p>
|
||||||
<p className="profile-hint">
|
<div className="profile-modal-actions">
|
||||||
Numéro utilisé par le livreur lors de la livraison. Peut être différent du numéro de votre compte.
|
<button
|
||||||
</p>
|
className="profile-modal-btn profile-modal-btn--cancel"
|
||||||
<div className="profile-group">
|
onClick={() => setShowSaveModal(false)}
|
||||||
<label>Téléphone par défaut</label>
|
>
|
||||||
<input
|
Annuler
|
||||||
type="tel"
|
</button>
|
||||||
value={defaultPhone}
|
<button
|
||||||
onChange={(e) => setDefaultPhone(e.target.value)}
|
className="profile-modal-btn profile-modal-btn--confirm"
|
||||||
placeholder="+33 6 12 34 56 78"
|
onClick={saveLocal}
|
||||||
/>
|
>
|
||||||
</div>
|
<FontAwesomeIcon icon={faCheckCircle} />{" "}
|
||||||
<div className="profile-group" style={{ marginTop: '1rem' }}>
|
Confirmer
|
||||||
<label>
|
</button>
|
||||||
<FontAwesomeIcon icon={faCommentDots} style={{ marginRight: '0.4rem' }} />
|
</div>
|
||||||
Pseudo Signal (optionnel)
|
</div>
|
||||||
</label>
|
</div>
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={signalPseudo}
|
|
||||||
onChange={(e) => setSignalPseudo(e.target.value)}
|
|
||||||
placeholder="@votre.pseudo.signal"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<button className="profile-btn profile-btn--secondary" onClick={() => setShowSaveModal(true)}>
|
|
||||||
<FontAwesomeIcon icon={faSave} /> Enregistrer les infos par défaut
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
{/* Section Telegram */}
|
|
||||||
{tgEnabled && (
|
|
||||||
<div className="profile-card">
|
|
||||||
<h2 className="profile-card-title">
|
|
||||||
<FontAwesomeIcon icon={faPaperPlane} className="profile-card-icon profile-card-icon--telegram" />
|
|
||||||
Notifications Telegram
|
|
||||||
</h2>
|
|
||||||
<p className="profile-hint">
|
|
||||||
Recevez vos notifications sur Telegram, même quand le site est fermé.
|
|
||||||
</p>
|
|
||||||
{tgLinked ? (
|
|
||||||
<div className="profile-telegram-linked">
|
|
||||||
<span className="profile-telegram-status">
|
|
||||||
<FontAwesomeIcon icon={faCheckCircle} /> Compte Telegram lié
|
|
||||||
</span>
|
|
||||||
<button className="profile-btn profile-btn--danger" onClick={handleUnlinkTelegram}>
|
|
||||||
<FontAwesomeIcon icon={faUnlink} /> Délier Telegram
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<button className="profile-btn profile-btn--telegram" onClick={handleLinkTelegram} disabled={tgLoading}>
|
|
||||||
<FontAwesomeIcon icon={faPaperPlane} />
|
|
||||||
{tgLoading ? ' Génération du lien...' : ' Lier mon compte Telegram'}
|
|
||||||
</button>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</>
|
||||||
)}
|
);
|
||||||
</div>
|
|
||||||
|
|
||||||
{showSaveModal && (
|
|
||||||
<div className="profile-modal-overlay" onClick={() => setShowSaveModal(false)}>
|
|
||||||
<div className="profile-modal" onClick={(e) => e.stopPropagation()}>
|
|
||||||
<button className="profile-modal-close" onClick={() => setShowSaveModal(false)}>
|
|
||||||
<FontAwesomeIcon icon={faTimes} />
|
|
||||||
</button>
|
|
||||||
<div className="profile-modal-icon">
|
|
||||||
<FontAwesomeIcon icon={faSave} />
|
|
||||||
</div>
|
|
||||||
<h3 className="profile-modal-title">Enregistrer les infos par défaut ?</h3>
|
|
||||||
<p className="profile-modal-body">
|
|
||||||
Adresse, téléphone de livraison et pseudo Signal seront sauvegardés localement et pré-remplis lors de vos prochaines commandes.
|
|
||||||
</p>
|
|
||||||
<div className="profile-modal-actions">
|
|
||||||
<button className="profile-modal-btn profile-modal-btn--cancel" onClick={() => setShowSaveModal(false)}>
|
|
||||||
Annuler
|
|
||||||
</button>
|
|
||||||
<button className="profile-modal-btn profile-modal-btn--confirm" onClick={saveLocal}>
|
|
||||||
<FontAwesomeIcon icon={faCheckCircle} /> Confirmer
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user