mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-04-05 20:51:26 +00:00
fix: Suppression envoi mail / création page feedback
This commit is contained in:
136
Front-End/src/app/[locale]/admin/feedback/page.js
Normal file
136
Front-End/src/app/[locale]/admin/feedback/page.js
Normal file
@ -0,0 +1,136 @@
|
||||
'use client';
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { sendFeedback } from '@/app/actions/emailAction';
|
||||
import { useNotification } from '@/context/NotificationContext';
|
||||
import { useEstablishment } from '@/context/EstablishmentContext';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import WisiwigTextArea from '@/components/Form/WisiwigTextArea';
|
||||
import InputText from '@/components/Form/InputText';
|
||||
import Button from '@/components/Form/Button';
|
||||
import SelectChoice from '@/components/Form/SelectChoice';
|
||||
import logger from '@/utils/logger';
|
||||
|
||||
export default function FeedbackPage() {
|
||||
const t = useTranslations('feedback');
|
||||
const { showNotification } = useNotification();
|
||||
const { selectedEstablishmentId, establishments, user } = useEstablishment();
|
||||
|
||||
// Récupérer les infos complètes de l'établissement sélectionné
|
||||
const selectedEstablishment = establishments?.find(
|
||||
(e) => e.id === selectedEstablishmentId
|
||||
);
|
||||
|
||||
const [category, setCategory] = useState('');
|
||||
const [subject, setSubject] = useState('');
|
||||
const [message, setMessage] = useState('');
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
const categoryChoices = [
|
||||
{ value: 'bug', label: t('category_bug') },
|
||||
{ value: 'feature', label: t('category_feature') },
|
||||
{ value: 'question', label: t('category_question') },
|
||||
{ value: 'other', label: t('category_other') },
|
||||
];
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!category || !subject || !message) {
|
||||
showNotification(t('error_required_fields'), 'error', t('error'));
|
||||
return;
|
||||
}
|
||||
|
||||
setIsSubmitting(true);
|
||||
|
||||
// Construire le nom de l'utilisateur (fallback vers l'email si nom indisponible)
|
||||
const userName = user
|
||||
? user.first_name && user.last_name
|
||||
? `${user.first_name} ${user.last_name}`
|
||||
: user.username || user.email?.split('@')[0] || ''
|
||||
: '';
|
||||
|
||||
const feedbackData = {
|
||||
category,
|
||||
subject,
|
||||
message,
|
||||
establishment: selectedEstablishment
|
||||
? {
|
||||
id: selectedEstablishment.id,
|
||||
name: selectedEstablishment.name,
|
||||
total_capacity: selectedEstablishment.total_capacity,
|
||||
evaluation_frequency: selectedEstablishment.evaluation_frequency,
|
||||
}
|
||||
: { id: selectedEstablishmentId },
|
||||
user_email: user?.email || '',
|
||||
user_name: userName,
|
||||
};
|
||||
|
||||
try {
|
||||
await sendFeedback(feedbackData);
|
||||
showNotification(t('success_message'), 'success', t('success'));
|
||||
// Réinitialiser les champs après succès
|
||||
setCategory('');
|
||||
setSubject('');
|
||||
setMessage('');
|
||||
} catch (error) {
|
||||
logger.error("Erreur lors de l'envoi du feedback:", { error });
|
||||
showNotification(t('error_sending'), 'error', t('error'));
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="h-full flex flex-col p-4">
|
||||
<div className="max-w-3xl mx-auto w-full">
|
||||
<h1 className="text-2xl font-headline font-bold text-gray-800 mb-2">
|
||||
{t('title')}
|
||||
</h1>
|
||||
<p className="text-gray-600 mb-6">{t('description')}</p>
|
||||
|
||||
<div className="bg-white rounded-lg shadow-md p-6">
|
||||
{/* Catégorie */}
|
||||
<SelectChoice
|
||||
name="category"
|
||||
label={t('category_label')}
|
||||
selected={category}
|
||||
callback={(e) => setCategory(e.target.value)}
|
||||
choices={categoryChoices}
|
||||
placeHolder={t('category_placeholder')}
|
||||
required
|
||||
/>
|
||||
|
||||
{/* Sujet */}
|
||||
<InputText
|
||||
name="subject"
|
||||
label={t('subject_label')}
|
||||
value={subject}
|
||||
onChange={(e) => setSubject(e.target.value)}
|
||||
placeholder={t('subject_placeholder')}
|
||||
required
|
||||
className="mb-4 mt-4"
|
||||
/>
|
||||
|
||||
{/* Message */}
|
||||
<div className="mb-6">
|
||||
<WisiwigTextArea
|
||||
label={t('message_label')}
|
||||
value={message}
|
||||
onChange={setMessage}
|
||||
placeholder={t('message_placeholder')}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Bouton d'envoi */}
|
||||
<div className="flex justify-end">
|
||||
<Button
|
||||
text={isSubmitting ? t('sending') : t('send')}
|
||||
onClick={handleSubmit}
|
||||
disabled={isSubmitting}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -12,6 +12,7 @@ import {
|
||||
Calendar,
|
||||
Settings,
|
||||
MessageSquare,
|
||||
MessageCircleHeart,
|
||||
} from 'lucide-react';
|
||||
|
||||
import Popup from '@/components/Popup';
|
||||
@ -24,6 +25,7 @@ import {
|
||||
FE_ADMIN_PLANNING_URL,
|
||||
FE_ADMIN_SETTINGS_URL,
|
||||
FE_ADMIN_MESSAGERIE_URL,
|
||||
FE_ADMIN_FEEDBACK_URL,
|
||||
} from '@/utils/Url';
|
||||
|
||||
import { disconnect } from '@/app/actions/authAction';
|
||||
@ -82,6 +84,12 @@ export default function Layout({ children }) {
|
||||
url: FE_ADMIN_MESSAGERIE_URL,
|
||||
icon: MessageSquare,
|
||||
},
|
||||
feedback: {
|
||||
id: 'feedback',
|
||||
name: t('feedback'),
|
||||
url: FE_ADMIN_FEEDBACK_URL,
|
||||
icon: MessageCircleHeart,
|
||||
},
|
||||
settings: {
|
||||
id: 'settings',
|
||||
name: t('settings'),
|
||||
|
||||
@ -1,17 +1,10 @@
|
||||
'use client';
|
||||
import React from 'react';
|
||||
import SidebarTabs from '@/components/SidebarTabs';
|
||||
import EmailSender from '@/components/Admin/EmailSender';
|
||||
import InstantMessaging from '@/components/Admin/InstantMessaging';
|
||||
import logger from '@/utils/logger';
|
||||
|
||||
export default function MessageriePage({ csrfToken }) {
|
||||
const tabs = [
|
||||
{
|
||||
id: 'email',
|
||||
label: 'Envoyer un Mail',
|
||||
content: <EmailSender csrfToken={csrfToken} />,
|
||||
},
|
||||
{
|
||||
id: 'instant',
|
||||
label: 'Messagerie Instantanée',
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import {
|
||||
BE_GESTIONEMAIL_SEARCH_RECIPIENTS_URL,
|
||||
BE_GESTIONEMAIL_SEND_EMAIL_URL,
|
||||
BE_GESTIONEMAIL_SEND_FEEDBACK_URL,
|
||||
} from '@/utils/Url';
|
||||
import { fetchWithAuth } from '@/utils/fetchWithAuth';
|
||||
import { getCsrfToken } from '@/utils/getCsrfToken';
|
||||
@ -19,3 +20,13 @@ export const sendEmail = async (messageData) => {
|
||||
body: JSON.stringify(messageData),
|
||||
});
|
||||
};
|
||||
|
||||
// Envoyer un feedback au support
|
||||
export const sendFeedback = async (feedbackData) => {
|
||||
const csrfToken = getCsrfToken();
|
||||
return fetchWithAuth(BE_GESTIONEMAIL_SEND_FEEDBACK_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'X-CSRFToken': csrfToken },
|
||||
body: JSON.stringify(feedbackData),
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user