diff --git a/front/app/orgs/[orgslug]/(withmenu)/layout.tsx b/front/app/orgs/[orgslug]/(withmenu)/layout.tsx index 2237ed06..5fa03f6a 100644 --- a/front/app/orgs/[orgslug]/(withmenu)/layout.tsx +++ b/front/app/orgs/[orgslug]/(withmenu)/layout.tsx @@ -2,7 +2,7 @@ import "@styles/globals.css"; import { Menu } from "@components/Objects/Menu/Menu"; import AuthProvider from "@components/Security/AuthProvider"; -export default async function RootLayout({ children, params }: { children: React.ReactNode , params :any}) { +export default function RootLayout({ children, params }: { children: React.ReactNode , params :any}) { return ( <> diff --git a/front/components/Objects/Menu/Menu.tsx b/front/components/Objects/Menu/Menu.tsx index f99bfe2e..b0f816b6 100644 --- a/front/components/Objects/Menu/Menu.tsx +++ b/front/components/Objects/Menu/Menu.tsx @@ -1,16 +1,30 @@ 'use client'; -import React from "react"; +import React, { use, useEffect } from "react"; import Link from "next/link"; -import { getUriWithOrg } from "@services/config/config"; +import { getAPIUrl, getUriWithOrg } from "@services/config/config"; import { getOrganizationContextInfo, getOrganizationContextInfoWithoutCredentials } from "@services/organizations/orgs"; import ClientComponentSkeleton from "@components/Utils/ClientComp"; import { HeaderProfileBox } from "@components/Security/HeaderProfileBox"; import MenuLinks from "./MenuLinks"; import { getOrgLogoMediaDirectory } from "@services/media/media"; +import { MessageSquareIcon } from "lucide-react"; +import { Tooltip } from "@radix-ui/react-tooltip"; +import ToolTip from "@components/StyledElements/Tooltip/Tooltip"; +import Modal from "@components/StyledElements/Modal/Modal"; +import FeedbackModal from "../Modals/Feedback/Feedback"; +import useSWR from "swr"; +import { swrFetcher } from "@services/utils/ts/requests"; -export const Menu = async (props: any) => { +export const Menu = (props: any) => { const orgslug = props.orgslug; - const org = await getOrganizationContextInfoWithoutCredentials(orgslug, { revalidate: 0, tags: ['organizations'] }); + const [feedbackModal, setFeedbackModal] = React.useState(false); + const { data: org, error: error, isLoading } = useSWR(`${getAPIUrl()}orgs/slug/${orgslug}`, swrFetcher); + + function closeFeedbackModal() { + setFeedbackModal(false); + } + + return ( <>
{
- {org.logo ? ( + {org?.logo ? ( Learnhouse {
- - - - +
-
- - - +
+ + } + dialogTitle="Feedback" + dialogDescription="An issue? A suggestion? a bug ? Let us know!" + dialogTrigger={ +
+ +
+ } + /> +
diff --git a/front/components/Objects/Modals/Feedback/Feedback.tsx b/front/components/Objects/Modals/Feedback/Feedback.tsx new file mode 100644 index 00000000..a4621d33 --- /dev/null +++ b/front/components/Objects/Modals/Feedback/Feedback.tsx @@ -0,0 +1,88 @@ +import FormLayout, { ButtonBlack, Flex, FormField, FormLabel, FormMessage, Input, Textarea } from "@components/StyledElements/Form/Form" +import { BarLoader } from "react-spinners" +import * as Form from '@radix-ui/react-form' +import React, { useState } from "react"; +import * as Sentry from '@sentry/browser'; +import { CheckCircleIcon } from "lucide-react"; +import { AuthContext } from "@components/Security/AuthProvider"; +import { randomUUID } from "crypto"; + +export const FeedbackModal = (user: any) => { + const auth: any = React.useContext(AuthContext); + + const [isSubmitting, setIsSubmitting] = useState(false); + const [view, setView] = useState<"feedbackForm" | "success">("feedbackForm") + const [feedbackMessage, setFeedbackMessage] = useState(""); + + + const handleSubmit = async (e: any) => { + e.preventDefault(); + setIsSubmitting(true); + + const user = auth.userInfo.user_object ? auth.userInfo.user_object : null; + const eventId = Sentry.captureMessage(`Feedback from ${user ? user.email : 'Anonymous'} - ${feedbackMessage}`); + + const userFeedback = { + event_id: eventId, + name: user ? user.full_name : 'Anonymous', + email: user ? user.email : 'Anonymous', + comments: feedbackMessage, + } + Sentry.captureUserFeedback(userFeedback); + setIsSubmitting(false); + setView("success"); + }; + + const handleFeedbackMessage = (event: React.ChangeEvent) => { + setFeedbackMessage(event.target.value) + }; + + if (view == "feedbackForm") { + return ( + + + + Feedback message + Please provide learning elements, separated by comma (,) + + +