+ );
+};
diff --git a/src/components/posts/ViewUserFavorites.tsx b/src/components/posts/ViewUserFavorites.tsx
index fc39f002..dd82f5ef 100644
--- a/src/components/posts/ViewUserFavorites.tsx
+++ b/src/components/posts/ViewUserFavorites.tsx
@@ -74,10 +74,11 @@ export const ViewUserFavorites: Component = () => {
});
const data = await response.json();
+ console.log("Get user favorites: ", data);
if (data) {
if (data.type === "single") {
console.log(data);
- setFavoritedItems(data.posts.body);
+ setFavoritedItems(data.posts);
setListName(data.list_name);
setListNumber(data.list_number);
setLoading(false);
diff --git a/src/i18n/UI/English.ts b/src/i18n/UI/English.ts
index 94868d81..b59f2a63 100644
--- a/src/i18n/UI/English.ts
+++ b/src/i18n/UI/English.ts
@@ -158,6 +158,7 @@ export const English = {
createUserAccount: "Create User Profile",
viewUserProfile: "My User Profile",
viewCreatorAccount: "My Creator Profile",
+ submitReview: "Submit Review"
},
messages: {
@@ -229,7 +230,8 @@ export const English = {
signIntoAddToFavorites: "Sign in to add to favorites",
resourceLinks: "Thanks for using LearnGrove! Here are your links:",
externalResourceDisclaimer: "LearnGrove provides links to these external resources as a convenience. LearnGrove is not responsible for and has no control over information at any external site. LearnGrove is not responsible for the quality, content, privacy, or reliability of any linked site. In no event shall LearnGrove be responsible for your use of a linked site. Many of these external sites are funded through advertising which may make use of cookies and other tracking technology to target your interests for that advertising. Please be careful when clicking on any links on an external site to ensure you are only accessing links you intend to.",
-
+ submitted: "Submitted",
+ overallReviewRequired: "Please include an overall rating for your review"
},
formLabels: {
@@ -394,7 +396,10 @@ export const English = {
"Tax category determines how sales tax will be calculated in states where LearnGrove collects and remits tax on your behalf. As stated in the Terms you are responsible for choosing the appropriate tax category for each resource you list. Click the link below to learn more.",
resourceTypes: "Please select all applicable resource types.",
price: "The price entered is the price charged to the customer. The creator will receive the remaining amount after fees. See Terms for more information about the LearnGrove fee structure.",
- secular: "LearnGrove acknowledges that a secular curriculum or resource could mean different things to different creators, learners and learning facilitators. At LearnGrove we use this term to refer to both faith-neutral resources as well as those that may teach a world view that is not in alignment with any particular religion but may teach concepts that are in direct conflict with particular religion. We leave it up to our creators to determine if they feel their resources are suitable for a secular environment. We strongly recommend that you include additional detail in your description to detail how your resource addresses various topics such as creation vs evolution, religious literary texts, etc."
+ secular: "LearnGrove acknowledges that a secular curriculum or resource could mean different things to different creators, learners and learning facilitators. At LearnGrove we use this term to refer to both faith-neutral resources as well as those that may teach a world view that is not in alignment with any particular religion but may teach concepts that are in direct conflict with particular religion. We leave it up to our creators to determine if they feel their resources are suitable for a secular environment. We strongly recommend that you include additional detail in your description to detail how your resource addresses various topics such as creation vs evolution, religious literary texts, etc.",
+ overallRatingDescription: "Please rate this resource on a scale of one to five, with one being the lowest rating and five being the highest.",
+ reviewTitleDescription: "The review title will appear at the top of your review. A short and specific description is recommended for the review title.",
+ reviewTextDescription: "The review text field provides more space for you to further explain your overall rating. We recommend one to three paragraphs.",
},
apiErrors: {
@@ -431,7 +436,9 @@ export const English = {
singleListFavoriteError: "Error getting single list favorites",
favoriteListError: "Error fetching favorite list",
multipleListFavoriteError: "Error handling multiple lists",
- },
+ problemPostingReview: "We're sorry, there was an issue posting your review. Please try again or contact LearnGrove support.",
+ noDataFound: "No data found",
+ },
socialModal: {
shareService: "Share this resource",
diff --git a/src/i18n/UI/French.ts b/src/i18n/UI/French.ts
index bafe1663..e0dc7454 100644
--- a/src/i18n/UI/French.ts
+++ b/src/i18n/UI/French.ts
@@ -153,6 +153,7 @@ export const French = {
createUserAccount: "Créer un profil utilisateur",
viewUserProfile: "Mon profil utilisateur",
viewCreatorAccount: "Mon profil de créateur",
+ submitReview: "Soumettre Critique",
},
messages: {
@@ -230,6 +231,8 @@ export const French = {
signIntoAddToFavorites: "Connectez-vous pour ajouter aux favoris",
resourceLinks: "Merci d'utiliser LearnGrove ! Voici vos liens:",
externalResourceDisclaimer: "LearnGrove fournit des liens vers ces ressources externes pour plus de commodité. LearnGrove n'est pas responsable et n'a aucun contrôle sur les informations contenues dans aucun site externe. LearnGrove n'est pas responsable de la qualité, du contenu, de la confidentialité ou de la fiabilité de tout site lié. En aucun cas LearnGrove ne sera responsable de votre utilisation d’un site lié. Beaucoup de ces sites externes sont financés par la publicité qui peut utiliser des cookies et d'autres technologies de suivi pour cibler vos intérêts pour cette publicité. Veuillez être prudent lorsque vous cliquez sur des liens sur un site externe pour vous assurer que vous accédez uniquement aux liens auxquels vous avez l'intention d'accéder.",
+ submitted: "Soumise",
+ overallReviewRequired: "Veuillez inclure une note globale pour votre avis",
},
formLabels: {
@@ -393,6 +396,9 @@ export const French = {
resourceTypes: "Veuillez sélectionner tous les types de ressources applicables.",
price: "Le prix saisi est le prix facturé au client. Le créateur recevra le montant restant après frais. Consultez les conditions pour plus d'informations sur la structure tarifaire LearnGrove.",
secular: "LearnGrove reconnaît qu'un programme ou une ressource laïque peut signifier différentes choses pour différents créateurs, apprenants et facilitateurs d'apprentissage. Chez LearnGrove, nous utilisons ce terme pour désigner à la fois les ressources neutres en matière de foi ainsi que celles qui peuvent enseigner une vision du monde qui n'est pas conforme à une religion particulière, mais qui peuvent enseigner des concepts qui sont en conflit direct avec une religion particulière. Nous laissons à nos créateurs le soin de déterminer s'ils estiment que leurs ressources sont adaptées à un environnement laïc. Nous vous recommandons fortement d'inclure des détails supplémentaires dans votre description pour détailler la manière dont votre ressource aborde divers sujets tels que la création par rapport à l'évolution, les textes littéraires religieux, etc.",
+ overallRatingDescription: "Veuillez évaluer cette ressource sur une échelle de un à cinq, un étant la note la plus basse et cinq la plus élevée.",
+ reviewTitleDescription: "Le titre de votre avis apparaîtra en haut de votre avis. Une description courte et précise est recommandée pour le titre de votre avis.",
+ reviewTextDescription: "Le champ de texte de l'avis vous offre plus d'espace pour expliquer plus en détail votre note globale. Nous vous recommandons d'écrire un à trois paragraphes.",
},
apiErrors: {
@@ -426,7 +432,9 @@ export const French = {
emailNotConfirmed:
"Correo electrónico no registrado. Si registró previamente esta dirección de correo electrónico, utilice la opción de olvidé mi contraseña que aparece a continuación; de lo contrario, utilice la opción de registro que aparece a continuación.",
noFavoriteLists: "Aucune liste de favoris trouvée",
- },
+ problemPostingReview: "Nous sommes désolés, un problème est survenu lors de la publication de votre avis. Veuillez réessayer ou contacter le support LearnGrove.",
+ noDataFound: "Aucune donnée trouvée",
+ },
socialModal: {
shareService: "Partager ce ressource",
diff --git a/src/i18n/UI/Spanish.ts b/src/i18n/UI/Spanish.ts
index 20f776ed..aa1ce307 100644
--- a/src/i18n/UI/Spanish.ts
+++ b/src/i18n/UI/Spanish.ts
@@ -156,6 +156,7 @@ export const Spanish = {
createUserAccount: "Crear perfil de usuario",
viewUserProfile: "Mi perfil de usuario",
viewCreatorAccount: "Mi perfil de creador",
+ submitReview: "Enviar Reseña",
},
messages: {
@@ -232,6 +233,8 @@ export const Spanish = {
signIntoAddToFavorites: "Inicie sesión para agregar a favoritos",
resourceLinks: "¡Gracias por usar LearnGrove! Aquí están sus enlaces:",
externalResourceDisclaimer: "LearnGrove proporciona enlaces a estos recursos externos para su comodidad. LearnGrove no es responsable ni tiene control sobre la información contenida en ningún sitio externo. LearnGrove no es responsable de la calidad, el contenido, la privacidad o la confiabilidad de ningún sitio vinculado. En ningún caso LearnGrove será responsable del uso que usted haga de un sitio vinculado. Muchos de estos sitios externos se financian a través de publicidad que puede utilizar cookies y otras tecnologías de seguimiento para orientar sus intereses para esa publicidad. Tenga cuidado al hacer clic en cualquier enlace de un sitio externo para asegurarse de acceder solo a los enlaces que desea.",
+ submitted: "Enviada",
+ overallReviewRequired: "Incluya una calificación general para su revisión",
},
formLabels: {
@@ -396,6 +399,9 @@ export const Spanish = {
resourceTypes: "Seleccione todos los tipos de recursos aplicables.",
price: "El precio introducido es el precio cobrado al cliente. El creador recibirá el importe restante después de las tarifas. Consulte los Términos para obtener más información sobre la estructura de tarifas de LearnGrove.",
secular: "LearnGrove reconoce que un plan de estudios o recurso secular podría significar cosas diferentes para diferentes creadores, estudiantes y facilitadores de aprendizaje. En LearnGrove utilizamos este término para referirnos tanto a los recursos neutrales a la fe como a aquellos que pueden enseñar una visión del mundo que no está alineada con ninguna religión en particular, pero que pueden enseñar conceptos que están en conflicto directo con una religión en particular. Dejamos en manos de nuestros creadores determinar si creen que sus recursos son adecuados para un entorno secular. Le recomendamos encarecidamente que incluya detalles adicionales en su descripción para detallar cómo su recurso aborda diversos temas, como creación versus evolución, textos literarios religiosos, etc.",
+ overallRatingDescription: "Califique este recurso en una escala del uno al cinco, siendo uno la calificación más baja y cinco la más alta.",
+ reviewTitleDescription: "El título de la reseña aparecerá en la parte superior de la misma. Se recomienda incluir una descripción breve y específica para el título de la reseña.",
+ reviewTextDescription: "El campo de texto de la reseña le ofrece más espacio para explicar con más detalle su calificación general. Recomendamos que incluya entre uno y tres párrafos.",
},
apiErrors: {
@@ -426,7 +432,9 @@ export const Spanish = {
emailNotConfirmed:
"Correo electrónico no registrado. Si registró previamente esta dirección de correo electrónico, utilice la opción de olvidé mi contraseña que aparece a continuación; de lo contrario, utilice la opción de registro que aparece a continuación.",
noFavoriteLists: "No se encontraron lista de favoritos",
- },
+ problemPostingReview: "Lo sentimos, se produjo un problema al publicar tu reseña. Vuelve a intentarlo o ponte en contacto con el servicio de asistencia de LearnGrove.",
+ noDataFound: "No se encontraron datos",
+ },
socialModal: {
shareService: "Comparte este recurso",
diff --git a/src/i18n/uiType.ts b/src/i18n/uiType.ts
index 233a524d..7d9e2ecb 100644
--- a/src/i18n/uiType.ts
+++ b/src/i18n/uiType.ts
@@ -161,6 +161,7 @@ export interface uiObject {
createUserAccount: string,
viewUserProfile: string,
viewCreatorAccount: string,
+ submitReview: string,
};
messages: {
@@ -220,6 +221,8 @@ export interface uiObject {
signIntoAddToFavorites: string;
resourceLinks: string;
externalResourceDisclaimer: string;
+ submitted: string,
+ overallReviewRequired: string,
};
formLabels: {
@@ -276,6 +279,7 @@ export interface uiObject {
downloadable: string;
whatDidYouThink: string;
overallRating: string;
+
reviewQ1: string;
reviewQ2: string;
reviewQ3: string;
@@ -283,7 +287,9 @@ export interface uiObject {
reviewQ5: string;
reviewQ6: string;
reviewTitle: string;
+
reviewText: string;
+
priceFilter: string;
freeResources: string;
listName: string;
@@ -364,6 +370,9 @@ export interface uiObject {
resourceTypes: string;
price: string;
secular: string;
+ overallRatingDescription: string,
+ reviewTitleDescription: string;
+ reviewTextDescription: string;
};
apiErrors: {
@@ -398,6 +407,8 @@ export interface uiObject {
singleListFavoriteError: string;
favoriteListError: string;
multipleListFavoriteError: string;
+ problemPostingReview: string;
+ noDataFound: string;
};
socialModal: {
diff --git a/src/lib/types.ts b/src/lib/types.ts
index 4dff310e..8c66fa6e 100644
--- a/src/lib/types.ts
+++ b/src/lib/types.ts
@@ -23,6 +23,7 @@ export interface Post {
unit_amount: number;
resource_links: string[];
created_at: number;
+ overall_review: number;
//These fields are not stored in the database and must be fetched from stripe (price) or set by the code
subject: Array | null;
@@ -84,6 +85,7 @@ export interface FilterPostsParams {
subtopics?: number[];
priceMin?: number;
priceMax?: number;
+ overallReview?: number;
}
export interface Orders{
@@ -100,11 +102,12 @@ export interface Order_Details{
}
export interface Review {
- resource_id : string,
- reviewer_id: string,
- review_title: string,
- review_text: string,
- overall_rating :number,
+ created_at: Date,
+ resource_id : string,
+ reviewer_id: string,
+ review_title: string,
+ review_text: string,
+ overall_rating :number,
}
export interface ListData {
diff --git a/src/pages/api/clientSubmitReviewResource.ts b/src/pages/api/clientSubmitReviewResource.ts
index e790498d..91fc446a 100644
--- a/src/pages/api/clientSubmitReviewResource.ts
+++ b/src/pages/api/clientSubmitReviewResource.ts
@@ -32,8 +32,8 @@ export const POST: APIRoute = async ({ request, redirect }) => {
// Validate the formData makes sure none of the fields are blank. Could probably do more than this like check for invalid phone numbers, blank strings, unselected location info etc.
if (
- !reviewTitle ||
- !reviewText ||
+ // !reviewTitle ||
+ // !reviewText ||
!overallRating ||
!resourceId ||
!userId ||
@@ -91,8 +91,8 @@ export const POST: APIRoute = async ({ request, redirect }) => {
let submission = {
resource_id: resourceId,
reviewer_id: userId,
- review_title: reviewTitle,
- review_text: reviewText,
+ review_title: reviewTitle || null,
+ review_text: reviewText || null,
overall_rating: overallRating,
};
@@ -107,7 +107,7 @@ export const POST: APIRoute = async ({ request, redirect }) => {
JSON.stringify({
// message: t("apiErrors.creatorCreateProfileError"),
//TODO: Internationalize
- message: "fail to insert "
+ message: t("apiErrors.problemPostingReview")
}),
{ status: 500 }
);
@@ -116,7 +116,7 @@ export const POST: APIRoute = async ({ request, redirect }) => {
JSON.stringify({
// message: t("apiErrors.noProfileData"),
//TODO: Internationalize
- message: "fail data fetch",
+ message: t("apiErrors.noDataFound"),
}),
{ status: 500 }
);
diff --git a/src/pages/api/fetchFilterPosts.ts b/src/pages/api/fetchFilterPosts.ts
index 253584a9..392d2920 100644
--- a/src/pages/api/fetchFilterPosts.ts
+++ b/src/pages/api/fetchFilterPosts.ts
@@ -32,9 +32,6 @@ export const POST: APIRoute = async ({ request, redirect }) => {
const values = ui[lang] as uiObject;
const postSubjects = values.subjectCategoryInfo.subjects;
const postSubtopics = values.subjectCategoryInfo.subtopics;
- // console.log("From: ", from);
- // console.log(" To: ", to);
- // console.log(subtopics);
try {
let query = supabase
@@ -93,8 +90,6 @@ export const POST: APIRoute = async ({ request, redirect }) => {
query = query.lte("price_value", priceMax);
}
- // console.log(query)
-
const { data: posts, error } = await query;
if (error) {
@@ -106,9 +101,6 @@ export const POST: APIRoute = async ({ request, redirect }) => {
{ status: 500 }
);
}
- // else {
- // console.log("Posts: ", posts.length);
- // }
const { data: gradeData, error: gradeError } = await supabase
.from("grade_level")
@@ -129,7 +121,6 @@ export const POST: APIRoute = async ({ request, redirect }) => {
let formattedPosts: Post[] = [];
if (posts && gradeData && resourceTypesData) {
- // console.log(posts);
formattedPosts = await Promise.all(
posts.map(async (post: Post) => {
diff --git a/src/pages/api/getAllReviews.ts b/src/pages/api/getAllReviews.ts
index 78792262..80b10ed8 100644
--- a/src/pages/api/getAllReviews.ts
+++ b/src/pages/api/getAllReviews.ts
@@ -13,7 +13,7 @@ export const POST: APIRoute = async ({ request, redirect }) => {
const { error, data } = await supabase
.from("reviews")
.select("*")
- .eq("resource_id",resource_id)
+ .eq("resource_id", resource_id)
if (error) {
console.log(error);
diff --git a/src/styles/global.css b/src/styles/global.css
index 8ad0a104..26dfc5be 100644
--- a/src/styles/global.css
+++ b/src/styles/global.css
@@ -58,23 +58,14 @@
@apply my-2 mr-2 flex h-20 w-20 items-center justify-center rounded-full border-2 border-border1 text-ptext1 dark:border-border1-DM dark:text-ptext1-DM md:h-24 md:w-24 md:border-4;
}
- #user-profile-ratings-div {
- unicode-bidi: bidi-override;
- direction: rtl;
- }
-
- #user-profile-ratings-div > span {
- display: inline-block;
- position: relative;
- width: 1.1em;
+ #user-profile-ratings-div > * {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 48px;
+ margin: 0px 2px;
font-size: 18px;
}
-
- #user-profile-ratings-div > span:hover:before,
- #user-profile-ratings-div > span:hover ~ span:before {
- content: "\2605";
- position: absolute;
- }
}
@layer utilities {
diff --git a/supabase/migrations/20241118205252_preventMultipleReviews.sql b/supabase/migrations/20241118205252_preventMultipleReviews.sql
new file mode 100644
index 00000000..c17ca698
--- /dev/null
+++ b/supabase/migrations/20241118205252_preventMultipleReviews.sql
@@ -0,0 +1,2 @@
+ALTER TABLE ONLY "public"."reviews"
+ ADD CONSTRAINT "reviews_resource_id_reviewer_id_key" UNIQUE ("resource_id", "reviewer_id")
\ No newline at end of file