Skip to content

Commit

Permalink
Review fixes: add email and telegram, move to home navbar
Browse files Browse the repository at this point in the history
  • Loading branch information
greatsamist committed Feb 29, 2024
1 parent 026215c commit 8b59612
Show file tree
Hide file tree
Showing 12 changed files with 173 additions and 72 deletions.
3 changes: 1 addition & 2 deletions packages/app/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { TopNavbarContextProvider } from '@/lib/context/TopNavbarContext'
import { generalMetadata } from '@/lib/utils/metadata'
import { Toaster } from '@/components/ui/sonner'
import CookieBanner from '@/components/misc/CookieBanner'
import Support from '@/components/misc/Support'

const ubuntu = Ubuntu({
weight: ['400', '500', '700'],
Expand Down Expand Up @@ -37,7 +36,7 @@ export default function RootLayout({
<ModalContextProvider>
<TopNavbarContextProvider>
{children}
<Support />

<div className="fixed bottom-4 left-4 z-50 mr-4">
<CookieBanner />
</div>
Expand Down
4 changes: 3 additions & 1 deletion packages/app/components/Layout/HomePageNavbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { useSIWE } from 'connectkit'
import useUserData from '@/lib/hooks/useUserData'
import SwitchOrganization from '@/app/studio/[organization]/components/SwitchOrganization'
import { IExtendedOrganization } from '@/lib/types'
import Support from '../misc/Support'
const getPages = (
pages: Page[],
isSignedIn: boolean,
Expand Down Expand Up @@ -124,6 +125,7 @@ const MobileNavBar = ({
</button>
)}
</div>
<Support />
{menuVisible && (
<Navbar
pages={getPages(
Expand Down Expand Up @@ -166,7 +168,7 @@ const PCNavBar = ({
<div className="flex flex-grow justify-center items-center">
{showSearchBar && <SearchBar />}
</div>

<Support />
<Navbar
pages={getPages(
pages,
Expand Down
17 changes: 15 additions & 2 deletions packages/app/components/misc/InfoHoverCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,36 @@ import {
HoverCardContent,
HoverCardTrigger,
} from '@/components/ui/hover-card'
import { Info } from 'lucide-react'
import { Info, LucideProps } from 'lucide-react'
import { ForwardRefExoticComponent } from 'react'

type IconType = ForwardRefExoticComponent<LucideProps> & {
displayName?: string
}

const InfoHoverCard = ({
title,
description,
size = 24,
stroke = 2,
Icon = Info,
iconClassName,
}: {
title: string
description: string
size?: number
stroke?: number
Icon?: IconType
iconClassName?: string
}) => {
return (
<HoverCard>
<HoverCardTrigger asChild>
<Info size={size} strokeWidth={stroke} />
<Icon
className={iconClassName}
size={size}
strokeWidth={stroke}
/>
</HoverCardTrigger>
<HoverCardContent className="w-80">
<div className="flex justify-between space-x-4">
Expand Down
48 changes: 43 additions & 5 deletions packages/app/components/misc/Support/SupportForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { Textarea } from '../../ui/textarea'
import { Button } from '../../ui/button'
import { Loader2 } from 'lucide-react'
import { UseFormReturn } from 'react-hook-form'
import { Input } from '@/components/ui/input'
import { getFormSubmitStatus } from '@/lib/utils/utils'

const SupportForm = ({
form,
Expand All @@ -20,14 +22,16 @@ const SupportForm = ({
}: {
form: UseFormReturn<{
message: string
telegram?: string
email?: string
}>
isLoading: boolean
onSubmit: (values: { message: string }) => void
handleClose: () => void
}) => {
return (
<div className="w-[250px]">
<h2 className="pb-4 font-bold">Write to us</h2>
<div>
<h2 className="pb-2 pt-3 font-bold">Send a support ticket</h2>
<Form {...form}>
<form
onError={(errors) => {
Expand All @@ -40,7 +44,9 @@ const SupportForm = ({
name="message"
render={({ field }) => (
<FormItem>
<FormLabel className="">Message</FormLabel>
<FormLabel required className="">
Message
</FormLabel>
<FormControl>
<Textarea
placeholder="Describe the bug here"
Expand All @@ -52,14 +58,46 @@ const SupportForm = ({
)}
/>

<div className="flex flex-row justify-between">
<FormField
control={form.control}
name="telegram"
render={({ field }) => (
<FormItem>
<FormLabel className="">Telegram Id</FormLabel>
<FormControl>
<Input placeholder="telegram Id" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>

<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel className="">Email</FormLabel>
<FormControl>
<Input placeholder="email" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>

<div className="flex gap-10 flex-row justify-between">
<Button
className="w-full"
onClick={handleClose}
type="button"
variant={'outline'}>
Cancel
</Button>
<Button type="submit">
<Button
className="w-full"
type="submit"
disabled={getFormSubmitStatus(form)}>
{isLoading ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />{' '}
Expand Down
118 changes: 66 additions & 52 deletions packages/app/components/misc/Support/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,31 @@ import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { toast } from 'sonner'
import { useSIWE } from 'connectkit'

import SupportForm from './SupportForm'
import { Button } from '../../ui/button'
import { ConnectWalletButton } from '../ConnectWalletButton'
import useClickOutside from '@/lib/hooks/useClickOutside'
import {
Credenza,
CredenzaContent,
CredenzaTitle,
CredenzaTrigger,
} from '@/components/ui/crezenda'
import InfoHoverCard from '../InfoHoverCard'

const Support = () => {
const [isSupportClicked, setIsSupportClicked] = useState(false)
const [isLoading, setIsLoading] = useState(false)
const [messageSent, setMessageSent] = useState(false)
const { isSignedIn } = useSIWE()
const [open, setOpen] = useState(false)
const form = useForm<z.infer<typeof supportSchema>>({
resolver: zodResolver(supportSchema),
defaultValues: {
message: '',
telegram: '',
email: '',
},
})
const supportRef = useRef(null)

function onSubmit(values: z.infer<typeof supportSchema>) {
setIsLoading(true)
if (!isSignedIn) {
Expand All @@ -47,60 +54,67 @@ const Support = () => {
setIsLoading(false)
})
}
useClickOutside(supportRef, () => setIsSupportClicked(false))

const handleClose = () => {
setMessageSent(false)
setIsSupportClicked(false)
setOpen(false)
}
return (
<div
ref={supportRef}
className="fixed right-2 top-36 bg-white cursor-pointer p-4">
{!isSupportClicked && (
<div onClick={() => setIsSupportClicked(true)}>
<Bug />
</div>
)}
<Credenza open={open} onOpenChange={setOpen}>
<CredenzaContent className="!z-50">
<CredenzaTitle>Bug/Content Error Report</CredenzaTitle>
<div>
<p className="pb-2">
Feel free to become a part of our{' '}
<a
className="text-primary font-semibold"
href="https://t.me/+p7TgdE06G-4zZDU0"
target="_blank"
rel="noopener noopener">
Telegram support
</a>{' '}
channel to stay informed about ticket updates, or
alternatively, you can raise an issue on{' '}
<a
className="text-primary font-semibold"
href="https://github.com/streamethorg/streameth-platform/issues"
target="_blank"
rel="noopener noopener">
GitHub.
</a>
</p>

{isSupportClicked &&
(!isSignedIn ? (
<div>
<p className="py-2">Sign in to send us a message</p>
<ConnectWalletButton />
</div>
) : messageSent ? (
<div className="w-[250px]">
<p className="font-bold pb-2">Message sent 🎉!!</p>
<p className="pb-2">
Feel free to become a part of our{' '}
<a
className="text-primary font-semibold"
href="https://t.me/+p7TgdE06G-4zZDU0"
target="_blank"
rel="noopener noopener">
Telegram support
</a>{' '}
channel to stay informed about ticket updates, or
alternatively, you can raise an issue on{' '}
<a
className="text-primary font-semibold"
href="https://github.com/streamethorg/streameth-platform/issues"
target="_blank"
rel="noopener noopener">
GitHub.
</a>
</p>
<Button onClick={handleClose}>Close</Button>
</div>
) : (
<SupportForm
form={form}
onSubmit={onSubmit}
isLoading={isLoading}
handleClose={handleClose}
{!isSignedIn ? (
<div>
<p className="py-2">Sign in to send us a message</p>
<ConnectWalletButton />
</div>
) : messageSent ? (
<div>
<p className="font-bold pb-2">Message sent 🎉!!</p>
<Button onClick={handleClose}>Close</Button>
</div>
) : (
<SupportForm
form={form}
onSubmit={onSubmit}
isLoading={isLoading}
handleClose={handleClose}
/>
)}
</div>
</CredenzaContent>
<CredenzaTrigger>
<div className="bg-red-500 cursor-pointer p-1 mr-2 lg:ml-auto lg:p-2 rounded-lg">
<InfoHoverCard
Icon={Bug}
iconClassName="w-4 h-4 lg:w-5 lg:h-5"
title="Bug/Content error report"
description="Directly send us a support ticket or report content error"
/>
))}
</div>
</div>
</CredenzaTrigger>
</Credenza>
)
}

Expand Down
21 changes: 13 additions & 8 deletions packages/app/components/ui/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,17 +90,22 @@ FormItem.displayName = 'FormItem'

const FormLabel = React.forwardRef<
React.ElementRef<typeof LabelPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>
>(({ className, ...props }, ref) => {
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> & {
required?: boolean
}
>(({ className, required, ...props }, ref) => {
const { error, formItemId } = useFormField()

return (
<Label
ref={ref}
className={cn(error && ' text-destructive', className)}
htmlFor={formItemId}
{...props}
/>
<div>
<Label
ref={ref}
className={cn(error && ' text-destructive', className)}
htmlFor={formItemId}
{...props}
/>
{required && <span className="text-red-500">*</span>}
</div>
)
})
FormLabel.displayName = 'FormLabel'
Expand Down
4 changes: 3 additions & 1 deletion packages/app/lib/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,11 @@ export const sessionSchema = z.object({
export const organizationSchema = z.object({
name: z.string().min(1, 'Name is required'),
logo: z.string().min(1, 'Logo is required'),
email: z.string(),
email: z.string().email(),
})

export const supportSchema = z.object({
message: z.string().min(1, 'Message is required'),
telegram: z.string().optional(),
email: z.string().optional(),
})
10 changes: 9 additions & 1 deletion packages/server/src/dtos/support/create-ticket.dto.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import { ISupport } from '@interfaces/support.interface';
import { IsNotEmpty, IsString } from 'class-validator';
import { IsNotEmpty, IsOptional, IsString } from 'class-validator';

export class CreateSupportTicketDto implements ISupport {
@IsNotEmpty()
@IsString()
message!: string;

@IsOptional()
@IsString()
telegram?: string;

@IsOptional()
@IsString()
email?: string;
}
2 changes: 2 additions & 0 deletions packages/server/src/interfaces/support.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { Document, Types } from 'mongoose';

export interface ISupport {
message: string;
telegram?: string;
email?: string;
}

export interface ISupportModel extends ISupport, Document {}
Loading

0 comments on commit 8b59612

Please sign in to comment.