Add feedback management features: Implement functions to add bonus points and mark feedback as read in the FeedbackManagement component. Update EventFeedback model to include isRead property, enhancing user interaction and feedback tracking.
This commit is contained in:
127
actions/admin/feedback.ts
Normal file
127
actions/admin/feedback.ts
Normal file
@@ -0,0 +1,127 @@
|
||||
"use server";
|
||||
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { auth } from "@/lib/auth";
|
||||
import { prisma } from "@/services/database";
|
||||
import { Role } from "@/prisma/generated/prisma/client";
|
||||
import { NotFoundError } from "@/services/errors";
|
||||
|
||||
function checkAdminAccess() {
|
||||
return async () => {
|
||||
const session = await auth();
|
||||
if (!session?.user || session.user.role !== Role.ADMIN) {
|
||||
throw new Error("Accès refusé");
|
||||
}
|
||||
return session;
|
||||
};
|
||||
}
|
||||
|
||||
export async function addFeedbackBonusPoints(
|
||||
userId: string,
|
||||
points: number
|
||||
) {
|
||||
try {
|
||||
await checkAdminAccess()();
|
||||
|
||||
// Vérifier que l'utilisateur existe
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
select: { id: true, score: true },
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
throw new NotFoundError("Utilisateur");
|
||||
}
|
||||
|
||||
// Ajouter les points
|
||||
const updatedUser = await prisma.user.update({
|
||||
where: { id: userId },
|
||||
data: {
|
||||
score: {
|
||||
increment: points,
|
||||
},
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
username: true,
|
||||
score: true,
|
||||
},
|
||||
});
|
||||
|
||||
revalidatePath("/admin");
|
||||
revalidatePath("/leaderboard");
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: `${points} points ajoutés avec succès`,
|
||||
data: updatedUser,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("Error adding bonus points:", error);
|
||||
|
||||
if (error instanceof NotFoundError) {
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
if (error instanceof Error && error.message === "Accès refusé") {
|
||||
return { success: false, error: "Accès refusé" };
|
||||
}
|
||||
|
||||
return {
|
||||
success: false,
|
||||
error: "Erreur lors de l'ajout des points",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function markFeedbackAsRead(feedbackId: string, isRead: boolean) {
|
||||
try {
|
||||
await checkAdminAccess()();
|
||||
|
||||
// Vérifier que le feedback existe
|
||||
const feedback = await prisma.eventFeedback.findUnique({
|
||||
where: { id: feedbackId },
|
||||
select: { id: true },
|
||||
});
|
||||
|
||||
if (!feedback) {
|
||||
throw new NotFoundError("Feedback");
|
||||
}
|
||||
|
||||
// Mettre à jour le statut
|
||||
const updatedFeedback = await prisma.eventFeedback.update({
|
||||
where: { id: feedbackId },
|
||||
data: {
|
||||
isRead,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
isRead: true,
|
||||
},
|
||||
});
|
||||
|
||||
revalidatePath("/admin");
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: isRead
|
||||
? "Feedback marqué comme lu"
|
||||
: "Feedback marqué comme non lu",
|
||||
data: updatedFeedback,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("Error marking feedback as read:", error);
|
||||
|
||||
if (error instanceof NotFoundError) {
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
if (error instanceof Error && error.message === "Accès refusé") {
|
||||
return { success: false, error: "Accès refusé" };
|
||||
}
|
||||
|
||||
return {
|
||||
success: false,
|
||||
error: "Erreur lors de la mise à jour du feedback",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import {
|
||||
addFeedbackBonusPoints,
|
||||
markFeedbackAsRead,
|
||||
} from "@/actions/admin/feedback";
|
||||
import { Button } from "@/components/ui";
|
||||
import Avatar from "@/components/ui/Avatar";
|
||||
|
||||
interface Feedback {
|
||||
id: string;
|
||||
rating: number;
|
||||
comment: string | null;
|
||||
isRead: boolean;
|
||||
createdAt: string;
|
||||
event: {
|
||||
id: string;
|
||||
@@ -17,6 +24,8 @@ interface Feedback {
|
||||
id: string;
|
||||
username: string;
|
||||
email: string;
|
||||
avatar: string | null;
|
||||
score: number;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -35,6 +44,10 @@ export default function FeedbackManagement() {
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState("");
|
||||
const [selectedEvent, setSelectedEvent] = useState<string | null>(null);
|
||||
const [addingPoints, setAddingPoints] = useState<Record<string, boolean>>(
|
||||
{}
|
||||
);
|
||||
const [markingRead, setMarkingRead] = useState<Record<string, boolean>>({});
|
||||
|
||||
useEffect(() => {
|
||||
fetchFeedbacks();
|
||||
@@ -92,9 +105,59 @@ export default function FeedbackManagement() {
|
||||
);
|
||||
};
|
||||
|
||||
const filteredFeedbacks = selectedEvent
|
||||
const handleAddPoints = async (userId: string, points: number) => {
|
||||
const key = `${userId}-${points}`;
|
||||
setAddingPoints((prev) => ({ ...prev, [key]: true }));
|
||||
setError("");
|
||||
|
||||
try {
|
||||
const result = await addFeedbackBonusPoints(userId, points);
|
||||
if (result.success) {
|
||||
// Rafraîchir les données pour voir les nouveaux scores
|
||||
await fetchFeedbacks();
|
||||
// Rafraîchir le score dans le header si l'utilisateur est connecté
|
||||
window.dispatchEvent(new Event("refreshUserScore"));
|
||||
} else {
|
||||
setError(result.error || "Erreur lors de l'ajout des points");
|
||||
}
|
||||
} catch {
|
||||
setError("Erreur lors de l'ajout des points");
|
||||
} finally {
|
||||
setAddingPoints((prev) => ({ ...prev, [key]: false }));
|
||||
}
|
||||
};
|
||||
|
||||
const handleMarkAsRead = async (feedbackId: string, isRead: boolean) => {
|
||||
setMarkingRead((prev) => ({ ...prev, [feedbackId]: true }));
|
||||
setError("");
|
||||
|
||||
try {
|
||||
const result = await markFeedbackAsRead(feedbackId, isRead);
|
||||
if (result.success) {
|
||||
// Rafraîchir les données pour voir le nouveau statut
|
||||
await fetchFeedbacks();
|
||||
} else {
|
||||
setError(result.error || "Erreur lors de la mise à jour");
|
||||
}
|
||||
} catch {
|
||||
setError("Erreur lors de la mise à jour");
|
||||
} finally {
|
||||
setMarkingRead((prev) => ({ ...prev, [feedbackId]: false }));
|
||||
}
|
||||
};
|
||||
|
||||
const filteredFeedbacks = (selectedEvent
|
||||
? feedbacks.filter((f) => f.event.id === selectedEvent)
|
||||
: feedbacks;
|
||||
: feedbacks
|
||||
).sort((a, b) => {
|
||||
// Trier : non lus en premier, puis par date décroissante
|
||||
if (a.isRead !== b.isRead) {
|
||||
return a.isRead ? 1 : -1;
|
||||
}
|
||||
return (
|
||||
new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
|
||||
);
|
||||
});
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
@@ -184,21 +247,46 @@ export default function FeedbackManagement() {
|
||||
{filteredFeedbacks.map((feedback) => (
|
||||
<div
|
||||
key={feedback.id}
|
||||
className="bg-black/40 border border-pixel-gold/20 rounded p-3 sm:p-4"
|
||||
className={`bg-black/40 border rounded p-3 sm:p-4 ${
|
||||
feedback.isRead
|
||||
? "border-pixel-gold/20 opacity-75"
|
||||
: "border-pixel-gold/50 bg-pixel-gold/5"
|
||||
}`}
|
||||
>
|
||||
<div className="flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3 mb-3">
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex flex-col sm:flex-row sm:items-center gap-1 sm:gap-3 mb-2">
|
||||
{/* En-tête utilisateur avec avatar */}
|
||||
<div className="flex items-center gap-2 sm:gap-3 mb-3">
|
||||
<Avatar
|
||||
src={feedback.user.avatar}
|
||||
username={feedback.user.username}
|
||||
size="md"
|
||||
borderClassName="border-pixel-gold/30"
|
||||
/>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex flex-col sm:flex-row sm:items-center gap-1 sm:gap-2 mb-1">
|
||||
<h4 className="text-white font-semibold text-sm sm:text-base break-words">
|
||||
{feedback.user.username}
|
||||
</h4>
|
||||
<span className="text-pixel-gold font-bold text-xs sm:text-sm">
|
||||
{feedback.user.score.toLocaleString("fr-FR")} pts
|
||||
</span>
|
||||
</div>
|
||||
<span className="text-gray-500 text-[10px] sm:text-xs break-all">
|
||||
{feedback.user.email}
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-pixel-gold text-xs sm:text-sm font-semibold mb-2 break-words">
|
||||
</div>
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<div className="text-pixel-gold text-xs sm:text-sm font-semibold break-words">
|
||||
{feedback.event.name}
|
||||
</div>
|
||||
{!feedback.isRead && (
|
||||
<span className="bg-pixel-gold/20 text-pixel-gold text-[10px] px-1.5 py-0.5 rounded uppercase font-semibold">
|
||||
Non lu
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-gray-500 text-[10px] sm:text-xs mb-2">
|
||||
{new Date(feedback.createdAt).toLocaleDateString(
|
||||
"fr-FR",
|
||||
@@ -212,8 +300,23 @@ export default function FeedbackManagement() {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-shrink-0">
|
||||
<div className="flex flex-col items-end gap-2 flex-shrink-0">
|
||||
{renderStars(feedback.rating)}
|
||||
<Button
|
||||
variant={feedback.isRead ? "secondary" : "success"}
|
||||
size="sm"
|
||||
onClick={() =>
|
||||
handleMarkAsRead(feedback.id, !feedback.isRead)
|
||||
}
|
||||
disabled={markingRead[feedback.id]}
|
||||
className="text-xs whitespace-nowrap"
|
||||
>
|
||||
{markingRead[feedback.id]
|
||||
? "..."
|
||||
: feedback.isRead
|
||||
? "Marquer non lu"
|
||||
: "Marquer lu"}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
{feedback.comment && (
|
||||
@@ -223,6 +326,39 @@ export default function FeedbackManagement() {
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
{/* Boutons pour ajouter des points bonus */}
|
||||
<div className="mt-3 pt-3 border-t border-pixel-gold/20 flex flex-wrap gap-2">
|
||||
<span className="text-gray-400 text-xs sm:text-sm mr-2">
|
||||
Points bonus:
|
||||
</span>
|
||||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
onClick={() => handleAddPoints(feedback.user.id, 10)}
|
||||
disabled={addingPoints[`${feedback.user.id}-10`]}
|
||||
className="text-xs"
|
||||
>
|
||||
{addingPoints[`${feedback.user.id}-10`] ? "..." : "+10"}
|
||||
</Button>
|
||||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
onClick={() => handleAddPoints(feedback.user.id, 100)}
|
||||
disabled={addingPoints[`${feedback.user.id}-100`]}
|
||||
className="text-xs"
|
||||
>
|
||||
{addingPoints[`${feedback.user.id}-100`] ? "..." : "+100"}
|
||||
</Button>
|
||||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
onClick={() => handleAddPoints(feedback.user.id, 1000)}
|
||||
disabled={addingPoints[`${feedback.user.id}-1000`]}
|
||||
className="text-xs"
|
||||
>
|
||||
{addingPoints[`${feedback.user.id}-1000`] ? "..." : "+1000"}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -211,6 +211,19 @@ export type IntNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
_max?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||
}
|
||||
|
||||
export type BoolFilter<$PrismaModel = never> = {
|
||||
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedBoolFilter<$PrismaModel> | boolean
|
||||
}
|
||||
|
||||
export type BoolWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedBoolWithAggregatesFilter<$PrismaModel> | boolean
|
||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedBoolFilter<$PrismaModel>
|
||||
_max?: Prisma.NestedBoolFilter<$PrismaModel>
|
||||
}
|
||||
|
||||
export type EnumChallengeStatusFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.ChallengeStatus | Prisma.EnumChallengeStatusFieldRefInput<$PrismaModel>
|
||||
in?: $Enums.ChallengeStatus[]
|
||||
@@ -467,6 +480,19 @@ export type NestedFloatNullableFilter<$PrismaModel = never> = {
|
||||
not?: Prisma.NestedFloatNullableFilter<$PrismaModel> | number | null
|
||||
}
|
||||
|
||||
export type NestedBoolFilter<$PrismaModel = never> = {
|
||||
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedBoolFilter<$PrismaModel> | boolean
|
||||
}
|
||||
|
||||
export type NestedBoolWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedBoolWithAggregatesFilter<$PrismaModel> | boolean
|
||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedBoolFilter<$PrismaModel>
|
||||
_max?: Prisma.NestedBoolFilter<$PrismaModel>
|
||||
}
|
||||
|
||||
export type NestedEnumChallengeStatusFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.ChallengeStatus | Prisma.EnumChallengeStatusFieldRefInput<$PrismaModel>
|
||||
in?: $Enums.ChallengeStatus[]
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1032,6 +1032,7 @@ export const EventFeedbackScalarFieldEnum = {
|
||||
eventId: 'eventId',
|
||||
rating: 'rating',
|
||||
comment: 'comment',
|
||||
isRead: 'isRead',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
} as const
|
||||
@@ -1138,6 +1139,13 @@ export type EnumEventTypeFieldRefInput<$PrismaModel> = FieldRefInputType<$Prisma
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reference to a field of type 'Boolean'
|
||||
*/
|
||||
export type BooleanFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Boolean'>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reference to a field of type 'ChallengeStatus'
|
||||
*/
|
||||
|
||||
@@ -141,6 +141,7 @@ export const EventFeedbackScalarFieldEnum = {
|
||||
eventId: 'eventId',
|
||||
rating: 'rating',
|
||||
comment: 'comment',
|
||||
isRead: 'isRead',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
} as const
|
||||
|
||||
@@ -40,6 +40,7 @@ export type EventFeedbackMinAggregateOutputType = {
|
||||
eventId: string | null
|
||||
rating: number | null
|
||||
comment: string | null
|
||||
isRead: boolean | null
|
||||
createdAt: Date | null
|
||||
updatedAt: Date | null
|
||||
}
|
||||
@@ -50,6 +51,7 @@ export type EventFeedbackMaxAggregateOutputType = {
|
||||
eventId: string | null
|
||||
rating: number | null
|
||||
comment: string | null
|
||||
isRead: boolean | null
|
||||
createdAt: Date | null
|
||||
updatedAt: Date | null
|
||||
}
|
||||
@@ -60,6 +62,7 @@ export type EventFeedbackCountAggregateOutputType = {
|
||||
eventId: number
|
||||
rating: number
|
||||
comment: number
|
||||
isRead: number
|
||||
createdAt: number
|
||||
updatedAt: number
|
||||
_all: number
|
||||
@@ -80,6 +83,7 @@ export type EventFeedbackMinAggregateInputType = {
|
||||
eventId?: true
|
||||
rating?: true
|
||||
comment?: true
|
||||
isRead?: true
|
||||
createdAt?: true
|
||||
updatedAt?: true
|
||||
}
|
||||
@@ -90,6 +94,7 @@ export type EventFeedbackMaxAggregateInputType = {
|
||||
eventId?: true
|
||||
rating?: true
|
||||
comment?: true
|
||||
isRead?: true
|
||||
createdAt?: true
|
||||
updatedAt?: true
|
||||
}
|
||||
@@ -100,6 +105,7 @@ export type EventFeedbackCountAggregateInputType = {
|
||||
eventId?: true
|
||||
rating?: true
|
||||
comment?: true
|
||||
isRead?: true
|
||||
createdAt?: true
|
||||
updatedAt?: true
|
||||
_all?: true
|
||||
@@ -197,6 +203,7 @@ export type EventFeedbackGroupByOutputType = {
|
||||
eventId: string
|
||||
rating: number
|
||||
comment: string | null
|
||||
isRead: boolean
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
_count: EventFeedbackCountAggregateOutputType | null
|
||||
@@ -230,6 +237,7 @@ export type EventFeedbackWhereInput = {
|
||||
eventId?: Prisma.StringFilter<"EventFeedback"> | string
|
||||
rating?: Prisma.IntFilter<"EventFeedback"> | number
|
||||
comment?: Prisma.StringNullableFilter<"EventFeedback"> | string | null
|
||||
isRead?: Prisma.BoolFilter<"EventFeedback"> | boolean
|
||||
createdAt?: Prisma.DateTimeFilter<"EventFeedback"> | Date | string
|
||||
updatedAt?: Prisma.DateTimeFilter<"EventFeedback"> | Date | string
|
||||
event?: Prisma.XOR<Prisma.EventScalarRelationFilter, Prisma.EventWhereInput>
|
||||
@@ -242,6 +250,7 @@ export type EventFeedbackOrderByWithRelationInput = {
|
||||
eventId?: Prisma.SortOrder
|
||||
rating?: Prisma.SortOrder
|
||||
comment?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
isRead?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
updatedAt?: Prisma.SortOrder
|
||||
event?: Prisma.EventOrderByWithRelationInput
|
||||
@@ -258,6 +267,7 @@ export type EventFeedbackWhereUniqueInput = Prisma.AtLeast<{
|
||||
eventId?: Prisma.StringFilter<"EventFeedback"> | string
|
||||
rating?: Prisma.IntFilter<"EventFeedback"> | number
|
||||
comment?: Prisma.StringNullableFilter<"EventFeedback"> | string | null
|
||||
isRead?: Prisma.BoolFilter<"EventFeedback"> | boolean
|
||||
createdAt?: Prisma.DateTimeFilter<"EventFeedback"> | Date | string
|
||||
updatedAt?: Prisma.DateTimeFilter<"EventFeedback"> | Date | string
|
||||
event?: Prisma.XOR<Prisma.EventScalarRelationFilter, Prisma.EventWhereInput>
|
||||
@@ -270,6 +280,7 @@ export type EventFeedbackOrderByWithAggregationInput = {
|
||||
eventId?: Prisma.SortOrder
|
||||
rating?: Prisma.SortOrder
|
||||
comment?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
isRead?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
updatedAt?: Prisma.SortOrder
|
||||
_count?: Prisma.EventFeedbackCountOrderByAggregateInput
|
||||
@@ -288,6 +299,7 @@ export type EventFeedbackScalarWhereWithAggregatesInput = {
|
||||
eventId?: Prisma.StringWithAggregatesFilter<"EventFeedback"> | string
|
||||
rating?: Prisma.IntWithAggregatesFilter<"EventFeedback"> | number
|
||||
comment?: Prisma.StringNullableWithAggregatesFilter<"EventFeedback"> | string | null
|
||||
isRead?: Prisma.BoolWithAggregatesFilter<"EventFeedback"> | boolean
|
||||
createdAt?: Prisma.DateTimeWithAggregatesFilter<"EventFeedback"> | Date | string
|
||||
updatedAt?: Prisma.DateTimeWithAggregatesFilter<"EventFeedback"> | Date | string
|
||||
}
|
||||
@@ -296,6 +308,7 @@ export type EventFeedbackCreateInput = {
|
||||
id?: string
|
||||
rating: number
|
||||
comment?: string | null
|
||||
isRead?: boolean
|
||||
createdAt?: Date | string
|
||||
updatedAt?: Date | string
|
||||
event: Prisma.EventCreateNestedOneWithoutFeedbacksInput
|
||||
@@ -308,6 +321,7 @@ export type EventFeedbackUncheckedCreateInput = {
|
||||
eventId: string
|
||||
rating: number
|
||||
comment?: string | null
|
||||
isRead?: boolean
|
||||
createdAt?: Date | string
|
||||
updatedAt?: Date | string
|
||||
}
|
||||
@@ -316,6 +330,7 @@ export type EventFeedbackUpdateInput = {
|
||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
rating?: Prisma.IntFieldUpdateOperationsInput | number
|
||||
comment?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
isRead?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
event?: Prisma.EventUpdateOneRequiredWithoutFeedbacksNestedInput
|
||||
@@ -328,6 +343,7 @@ export type EventFeedbackUncheckedUpdateInput = {
|
||||
eventId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
rating?: Prisma.IntFieldUpdateOperationsInput | number
|
||||
comment?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
isRead?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
@@ -338,6 +354,7 @@ export type EventFeedbackCreateManyInput = {
|
||||
eventId: string
|
||||
rating: number
|
||||
comment?: string | null
|
||||
isRead?: boolean
|
||||
createdAt?: Date | string
|
||||
updatedAt?: Date | string
|
||||
}
|
||||
@@ -346,6 +363,7 @@ export type EventFeedbackUpdateManyMutationInput = {
|
||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
rating?: Prisma.IntFieldUpdateOperationsInput | number
|
||||
comment?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
isRead?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
@@ -356,6 +374,7 @@ export type EventFeedbackUncheckedUpdateManyInput = {
|
||||
eventId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
rating?: Prisma.IntFieldUpdateOperationsInput | number
|
||||
comment?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
isRead?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
@@ -381,6 +400,7 @@ export type EventFeedbackCountOrderByAggregateInput = {
|
||||
eventId?: Prisma.SortOrder
|
||||
rating?: Prisma.SortOrder
|
||||
comment?: Prisma.SortOrder
|
||||
isRead?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
updatedAt?: Prisma.SortOrder
|
||||
}
|
||||
@@ -395,6 +415,7 @@ export type EventFeedbackMaxOrderByAggregateInput = {
|
||||
eventId?: Prisma.SortOrder
|
||||
rating?: Prisma.SortOrder
|
||||
comment?: Prisma.SortOrder
|
||||
isRead?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
updatedAt?: Prisma.SortOrder
|
||||
}
|
||||
@@ -405,6 +426,7 @@ export type EventFeedbackMinOrderByAggregateInput = {
|
||||
eventId?: Prisma.SortOrder
|
||||
rating?: Prisma.SortOrder
|
||||
comment?: Prisma.SortOrder
|
||||
isRead?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
updatedAt?: Prisma.SortOrder
|
||||
}
|
||||
@@ -497,10 +519,15 @@ export type EventFeedbackUncheckedUpdateManyWithoutEventNestedInput = {
|
||||
deleteMany?: Prisma.EventFeedbackScalarWhereInput | Prisma.EventFeedbackScalarWhereInput[]
|
||||
}
|
||||
|
||||
export type BoolFieldUpdateOperationsInput = {
|
||||
set?: boolean
|
||||
}
|
||||
|
||||
export type EventFeedbackCreateWithoutUserInput = {
|
||||
id?: string
|
||||
rating: number
|
||||
comment?: string | null
|
||||
isRead?: boolean
|
||||
createdAt?: Date | string
|
||||
updatedAt?: Date | string
|
||||
event: Prisma.EventCreateNestedOneWithoutFeedbacksInput
|
||||
@@ -511,6 +538,7 @@ export type EventFeedbackUncheckedCreateWithoutUserInput = {
|
||||
eventId: string
|
||||
rating: number
|
||||
comment?: string | null
|
||||
isRead?: boolean
|
||||
createdAt?: Date | string
|
||||
updatedAt?: Date | string
|
||||
}
|
||||
@@ -549,6 +577,7 @@ export type EventFeedbackScalarWhereInput = {
|
||||
eventId?: Prisma.StringFilter<"EventFeedback"> | string
|
||||
rating?: Prisma.IntFilter<"EventFeedback"> | number
|
||||
comment?: Prisma.StringNullableFilter<"EventFeedback"> | string | null
|
||||
isRead?: Prisma.BoolFilter<"EventFeedback"> | boolean
|
||||
createdAt?: Prisma.DateTimeFilter<"EventFeedback"> | Date | string
|
||||
updatedAt?: Prisma.DateTimeFilter<"EventFeedback"> | Date | string
|
||||
}
|
||||
@@ -557,6 +586,7 @@ export type EventFeedbackCreateWithoutEventInput = {
|
||||
id?: string
|
||||
rating: number
|
||||
comment?: string | null
|
||||
isRead?: boolean
|
||||
createdAt?: Date | string
|
||||
updatedAt?: Date | string
|
||||
user: Prisma.UserCreateNestedOneWithoutEventFeedbacksInput
|
||||
@@ -567,6 +597,7 @@ export type EventFeedbackUncheckedCreateWithoutEventInput = {
|
||||
userId: string
|
||||
rating: number
|
||||
comment?: string | null
|
||||
isRead?: boolean
|
||||
createdAt?: Date | string
|
||||
updatedAt?: Date | string
|
||||
}
|
||||
@@ -601,6 +632,7 @@ export type EventFeedbackCreateManyUserInput = {
|
||||
eventId: string
|
||||
rating: number
|
||||
comment?: string | null
|
||||
isRead?: boolean
|
||||
createdAt?: Date | string
|
||||
updatedAt?: Date | string
|
||||
}
|
||||
@@ -609,6 +641,7 @@ export type EventFeedbackUpdateWithoutUserInput = {
|
||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
rating?: Prisma.IntFieldUpdateOperationsInput | number
|
||||
comment?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
isRead?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
event?: Prisma.EventUpdateOneRequiredWithoutFeedbacksNestedInput
|
||||
@@ -619,6 +652,7 @@ export type EventFeedbackUncheckedUpdateWithoutUserInput = {
|
||||
eventId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
rating?: Prisma.IntFieldUpdateOperationsInput | number
|
||||
comment?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
isRead?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
@@ -628,6 +662,7 @@ export type EventFeedbackUncheckedUpdateManyWithoutUserInput = {
|
||||
eventId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
rating?: Prisma.IntFieldUpdateOperationsInput | number
|
||||
comment?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
isRead?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
@@ -637,6 +672,7 @@ export type EventFeedbackCreateManyEventInput = {
|
||||
userId: string
|
||||
rating: number
|
||||
comment?: string | null
|
||||
isRead?: boolean
|
||||
createdAt?: Date | string
|
||||
updatedAt?: Date | string
|
||||
}
|
||||
@@ -645,6 +681,7 @@ export type EventFeedbackUpdateWithoutEventInput = {
|
||||
id?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
rating?: Prisma.IntFieldUpdateOperationsInput | number
|
||||
comment?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
isRead?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
user?: Prisma.UserUpdateOneRequiredWithoutEventFeedbacksNestedInput
|
||||
@@ -655,6 +692,7 @@ export type EventFeedbackUncheckedUpdateWithoutEventInput = {
|
||||
userId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
rating?: Prisma.IntFieldUpdateOperationsInput | number
|
||||
comment?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
isRead?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
@@ -664,6 +702,7 @@ export type EventFeedbackUncheckedUpdateManyWithoutEventInput = {
|
||||
userId?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
rating?: Prisma.IntFieldUpdateOperationsInput | number
|
||||
comment?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
|
||||
isRead?: Prisma.BoolFieldUpdateOperationsInput | boolean
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
@@ -676,6 +715,7 @@ export type EventFeedbackSelect<ExtArgs extends runtime.Types.Extensions.Interna
|
||||
eventId?: boolean
|
||||
rating?: boolean
|
||||
comment?: boolean
|
||||
isRead?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
event?: boolean | Prisma.EventDefaultArgs<ExtArgs>
|
||||
@@ -688,6 +728,7 @@ export type EventFeedbackSelectCreateManyAndReturn<ExtArgs extends runtime.Types
|
||||
eventId?: boolean
|
||||
rating?: boolean
|
||||
comment?: boolean
|
||||
isRead?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
event?: boolean | Prisma.EventDefaultArgs<ExtArgs>
|
||||
@@ -700,6 +741,7 @@ export type EventFeedbackSelectUpdateManyAndReturn<ExtArgs extends runtime.Types
|
||||
eventId?: boolean
|
||||
rating?: boolean
|
||||
comment?: boolean
|
||||
isRead?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
event?: boolean | Prisma.EventDefaultArgs<ExtArgs>
|
||||
@@ -712,11 +754,12 @@ export type EventFeedbackSelectScalar = {
|
||||
eventId?: boolean
|
||||
rating?: boolean
|
||||
comment?: boolean
|
||||
isRead?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
}
|
||||
|
||||
export type EventFeedbackOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "userId" | "eventId" | "rating" | "comment" | "createdAt" | "updatedAt", ExtArgs["result"]["eventFeedback"]>
|
||||
export type EventFeedbackOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "userId" | "eventId" | "rating" | "comment" | "isRead" | "createdAt" | "updatedAt", ExtArgs["result"]["eventFeedback"]>
|
||||
export type EventFeedbackInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
event?: boolean | Prisma.EventDefaultArgs<ExtArgs>
|
||||
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
|
||||
@@ -742,6 +785,7 @@ export type $EventFeedbackPayload<ExtArgs extends runtime.Types.Extensions.Inter
|
||||
eventId: string
|
||||
rating: number
|
||||
comment: string | null
|
||||
isRead: boolean
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
}, ExtArgs["result"]["eventFeedback"]>
|
||||
@@ -1174,6 +1218,7 @@ export interface EventFeedbackFieldRefs {
|
||||
readonly eventId: Prisma.FieldRef<"EventFeedback", 'String'>
|
||||
readonly rating: Prisma.FieldRef<"EventFeedback", 'Int'>
|
||||
readonly comment: Prisma.FieldRef<"EventFeedback", 'String'>
|
||||
readonly isRead: Prisma.FieldRef<"EventFeedback", 'Boolean'>
|
||||
readonly createdAt: Prisma.FieldRef<"EventFeedback", 'DateTime'>
|
||||
readonly updatedAt: Prisma.FieldRef<"EventFeedback", 'DateTime'>
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
-- RedefineTables
|
||||
PRAGMA defer_foreign_keys=ON;
|
||||
PRAGMA foreign_keys=OFF;
|
||||
CREATE TABLE "new_EventFeedback" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"userId" TEXT NOT NULL,
|
||||
"eventId" TEXT NOT NULL,
|
||||
"rating" INTEGER NOT NULL,
|
||||
"comment" TEXT,
|
||||
"isRead" BOOLEAN NOT NULL DEFAULT false,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL,
|
||||
CONSTRAINT "EventFeedback_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT "EventFeedback_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
INSERT INTO "new_EventFeedback" ("comment", "createdAt", "eventId", "id", "rating", "updatedAt", "userId") SELECT "comment", "createdAt", "eventId", "id", "rating", "updatedAt", "userId" FROM "EventFeedback";
|
||||
DROP TABLE "EventFeedback";
|
||||
ALTER TABLE "new_EventFeedback" RENAME TO "EventFeedback";
|
||||
CREATE INDEX "EventFeedback_userId_idx" ON "EventFeedback"("userId");
|
||||
CREATE INDEX "EventFeedback_eventId_idx" ON "EventFeedback"("eventId");
|
||||
CREATE INDEX "EventFeedback_isRead_idx" ON "EventFeedback"("isRead");
|
||||
CREATE UNIQUE INDEX "EventFeedback_userId_eventId_key" ON "EventFeedback"("userId", "eventId");
|
||||
PRAGMA foreign_keys=ON;
|
||||
PRAGMA defer_foreign_keys=OFF;
|
||||
@@ -84,6 +84,7 @@ model EventFeedback {
|
||||
eventId String
|
||||
rating Int
|
||||
comment String?
|
||||
isRead Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)
|
||||
@@ -92,6 +93,7 @@ model EventFeedback {
|
||||
@@unique([userId, eventId])
|
||||
@@index([userId])
|
||||
@@index([eventId])
|
||||
@@index([isRead])
|
||||
}
|
||||
|
||||
model SitePreferences {
|
||||
|
||||
@@ -98,6 +98,8 @@ export class EventFeedbackService {
|
||||
id: true,
|
||||
username: true,
|
||||
email: true,
|
||||
avatar: true,
|
||||
score: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user