Skip to content

Commit

Permalink
feat: bug reporting by user on the app
Browse files Browse the repository at this point in the history
  • Loading branch information
tomaspalma committed Oct 12, 2024
1 parent 8a15ab2 commit 4d362bd
Show file tree
Hide file tree
Showing 7 changed files with 363 additions and 10 deletions.
40 changes: 37 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@
"dependencies": {
"@headlessui/react": "^1.7.17",
"@heroicons/react": "^2.1.1",
"@hookform/resolvers": "^3.9.0",
"@radix-ui/react-alert-dialog": "^1.0.5",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-scroll-area": "^1.0.5",
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-toast": "^1.1.5",
"@radix-ui/react-toggle": "^1.0.3",
Expand Down Expand Up @@ -42,6 +43,7 @@
"plausible-tracker": "^0.3.9",
"react": "^18.2.0",
"react-dom": "^18.1.0",
"react-hook-form": "^7.53.0",
"react-router-dom": "^6.3.0",
"react-sortablejs": "^6.1.4",
"react-toastify": "^9.1.1",
Expand All @@ -53,7 +55,8 @@
"usehooks-ts": "^2.6.0",
"vite": "^5.4.6",
"vite-tsconfig-paths": "^4.3.2",
"web-vitals": "^2.1.4"
"web-vitals": "^2.1.4",
"zod": "^3.23.8"
},
"scripts": {
"dev": "vite --host",
Expand Down
111 changes: 111 additions & 0 deletions src/components/FeedbackReport.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import * as Sentry from "@sentry/react";
import { BugAntIcon } from "@heroicons/react/24/solid"
import { DropdownMenu } from "@radix-ui/react-dropdown-menu"
import { Button } from "./ui/button"
import { DropdownMenuContent, DropdownMenuTrigger } from "./ui/dropdown-menu"
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "./ui/form";
import { useForm } from "react-hook-form";
import { Input } from "./ui/input";
import { Textarea } from "./ui/textarea";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod"
import { useToast } from "./ui/use-toast";
import { useState } from "react";
import { Tabs, TabsList, TabsTrigger } from "./ui/tabs";

enum ReportType {
Bug = 1,
Suggestion,
}

const reportTypeString = ["Bug", "Sugestão"]
const reportTypeSuccessMessage = ["O bug foi submetido com sucesso", "A sugestão foi submetida com sucesso"]

const bugSchema = z.object({
email: z.string().optional(),
description: z.string({ message: "É necessário descreveres o bug" })
})

export const FeedbackReport = () => {
const [open, setOpen] = useState<boolean>(false);
const [reportType, setReportType] = useState<ReportType>(ReportType.Bug);

const { toast } = useToast();

const form = useForm<z.infer<typeof bugSchema>>({
resolver: zodResolver(bugSchema),
defaultValues: {
email: undefined,
description: undefined
},
});

const { register } = form;

const onSubmit = (values: z.infer<typeof bugSchema>) => {
const eventId = Sentry.captureMessage(reportTypeString[reportType]);

const userFeedback = {
email: values.email ?? "",
message: values.description,
associatedEventId: eventId,
};
Sentry.captureFeedback(userFeedback);

setOpen(false);
toast({
title: "Obrigado!",
description: reportTypeSuccessMessage[reportType],
duration: 3000,
})
}

return <DropdownMenu open={open} onOpenChange={setOpen}>
<DropdownMenuTrigger asChild>
<Button variant="icon">
<BugAntIcon className="h-5 w-5 text-black" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<Tabs defaultValue="bug">
<TabsList className="w-full">
<TabsTrigger value="bug" onClick={() => setReportType(ReportType.Bug)}>Bug</TabsTrigger>
<TabsTrigger value="suggestion" onClick={() => setReportType(ReportType.Suggestion)}>Sugestão</TabsTrigger>
</TabsList>
</Tabs>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-col gap-y-4 p-2">
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem className="w-full">
<FormLabel>Email (opcional)</FormLabel>
<FormControl>
<Input placeholder="Email" {...field} {...register("email")} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>

<FormField
control={form.control}
name="description"
render={({ field }) => (
<FormItem>
<FormLabel>Descrição</FormLabel>
<FormControl>
<Textarea placeholder="Descrição" {...field} {...register("description")} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>

<Button type="submit">Submeter</Button>
</form>
</Form>
</DropdownMenuContent >
</DropdownMenu >
}
6 changes: 3 additions & 3 deletions src/components/layout/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from '@heroicons/react/24/outline'
import { LogoNIAEFEUPImage } from '../../images'
import { getPath, config } from '../../utils'
import { FeedbackReport } from '../FeedbackReport'

const navigation = [
{
Expand Down Expand Up @@ -80,9 +81,7 @@ const Header = ({ siteTitle, location }: Props) => {
))}
</div>

<div className="hidden self-center md:inline-flex">


<div className="hidden self-center md:inline-flex md:items-center">
<DarkModeSwitch />
</div>
</div>
Expand Down Expand Up @@ -127,6 +126,7 @@ const Hamburger = ({ open }: HamburgerProps) => (
<div className="flex items-center space-x-1">

<DarkModeSwitch />
<FeedbackReport />

<Disclosure.Button className="group text-gray-800 transition duration-200 ease-in dark:text-white md:hidden">
<span className="sr-only">Open nav menu</span>
Expand Down
7 changes: 6 additions & 1 deletion src/components/layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useEffect } from 'react'
import Header from './Header'
import Footer from './Footer'
import classNames from 'classnames'
import { FeedbackReport } from '../FeedbackReport'

type Props = {
children: JSX.Element
Expand All @@ -18,8 +19,12 @@ const Layout = ({ children, location, liquid, title }: Props) => {
return (
<div
id="layout"
className="flex min-h-screen flex-col bg-light font-prose font-normal text-gray-800 opacity-[99%] dark:bg-darkest dark:text-white"
className="min-h-screen flex-col bg-light font-prose font-normal text-gray-800 opacity-[99%] dark:bg-darkest dark:text-white"
>
<div className="hidden md:flex fixed bottom-0 left-0 mb-4 ml-4 rounded-full shadow-lg bg-white border">
<FeedbackReport />
</div>

<Header location={location} siteTitle="Time Table Selector" />
<div className={classNames(liquid ? 'my-auto' : 'mb-auto')}>{children}</div>
<Footer />
Expand Down
Loading

0 comments on commit 4d362bd

Please sign in to comment.