-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Simple assistant onboarding #382
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
30 commits
Select commit
Hold shift + click to select a range
869e6f4
assistant onboarding skeleton
elie222 d1ab915
add skip button. adjust copy
elie222 96312b1
set category form
elie222 0441992
move to own file
elie222 c469d6f
use actions instead of api routes for cold email settings
elie222 1c46bfb
save cold email setting and basic rules
elie222 4d25ab7
Merge branch 'main' into assistant-onboarding
elie222 f2f72a2
Merge branch 'main' into assistant-onboarding
elie222 d1c0e26
Merge branch 'main' into assistant-onboarding
elie222 8741e2b
enable reply zero in assistant setup
elie222 fe9f5a3
styling
elie222 36fd96b
create rules after onboarding
elie222 5334a40
Enable draft replies
elie222 cd2d8dc
update via onboarding
elie222 a8afcdf
jump to next step faster
elie222 b22d555
adjust copy
elie222 ec560dc
redirect to assistant onboarding
elie222 f2c4d32
hide show me around sooner
elie222 abb8c54
add set up link
elie222 73fdc47
scan old emails if none in reply tracker
elie222 0d64d27
warn
elie222 f454c39
skip processed emails
elie222 97efd72
hide scan history button
elie222 e4ed0ca
process emails when enabling reply zero
elie222 6b1f596
skip loading reply zero if already enabled
elie222 6b10579
fix api key for process previous
elie222 8621ade
adjust initial set up screen
elie222 1325c26
fix enabled check
elie222 6d003dc
adjust onboarding link
elie222 96ee418
fix error
elie222 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export const ONBOARDING_COOKIE_NAME = "viewed_onboarding"; |
187 changes: 187 additions & 0 deletions
187
apps/web/app/(app)/automation/onboarding/CategoriesSetup.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,187 @@ | ||
| "use client"; | ||
|
|
||
| import { useCallback } from "react"; | ||
| import Link from "next/link"; | ||
| import { useRouter } from "next/navigation"; | ||
| import { useForm } from "react-hook-form"; | ||
| import { zodResolver } from "@hookform/resolvers/zod"; | ||
| import type { ControllerRenderProps } from "react-hook-form"; | ||
| import { | ||
| Mail, | ||
| Newspaper, | ||
| Megaphone, | ||
| Calendar, | ||
| Receipt, | ||
| Bell, | ||
| Users, | ||
| } from "lucide-react"; | ||
| import { TypographyH3, TypographyP } from "@/components/Typography"; | ||
| import { Card, CardContent } from "@/components/ui/card"; | ||
| import { Button } from "@/components/ui/button"; | ||
| import { Form, FormControl, FormField, FormItem } from "@/components/ui/form"; | ||
| import { | ||
| Select, | ||
| SelectContent, | ||
| SelectItem, | ||
| SelectTrigger, | ||
| SelectValue, | ||
| } from "@/components/ui/select"; | ||
| import { createRulesOnboardingAction } from "@/utils/actions/rule"; | ||
| import { isActionError } from "@/utils/error"; | ||
| import { toastError } from "@/components/Toast"; | ||
| import { | ||
| createRulesOnboardingBody, | ||
| type CreateRulesOnboardingBody, | ||
| } from "@/utils/actions/rule.validation"; | ||
|
|
||
| const NEXT_URL = "/automation/onboarding/draft-replies"; | ||
|
|
||
| export function CategoriesSetup() { | ||
| const router = useRouter(); | ||
|
|
||
| const form = useForm<CreateRulesOnboardingBody>({ | ||
| resolver: zodResolver(createRulesOnboardingBody), | ||
| defaultValues: { | ||
| toReply: "label", | ||
| newsletters: "label", | ||
| marketing: "label_archive", | ||
| calendar: "label", | ||
| receipts: "label", | ||
| notifications: "label", | ||
| coldEmails: "label_archive", | ||
| }, | ||
| }); | ||
|
|
||
| const onSubmit = useCallback( | ||
| async (data: CreateRulesOnboardingBody) => { | ||
| // runs in background so we can move on to next step faster | ||
| createRulesOnboardingAction(data); | ||
| router.push(NEXT_URL); | ||
| }, | ||
| [router], | ||
| ); | ||
|
|
||
| return ( | ||
| <Form {...form}> | ||
| <form onSubmit={form.handleSubmit(onSubmit)}> | ||
| <TypographyH3 className="mt-2">Set up your assistant</TypographyH3> | ||
|
|
||
| <TypographyP className="mt-2"> | ||
| Choose how you want your emails organized. | ||
| <br /> | ||
| You can add custom categories and rules later. | ||
| </TypographyP> | ||
|
|
||
| <div className="mt-4 grid grid-cols-1 gap-4"> | ||
| <CategoryCard | ||
| label="To Reply" | ||
| id="toReply" | ||
| icon={<Mail className="h-5 w-5 text-blue-500" />} | ||
| form={form} | ||
| /> | ||
| <CategoryCard | ||
| label="Newsletters" | ||
| id="newsletters" | ||
| icon={<Newspaper className="h-5 w-5 text-purple-500" />} | ||
| form={form} | ||
| /> | ||
| <CategoryCard | ||
| label="Marketing" | ||
| id="marketing" | ||
| icon={<Megaphone className="h-5 w-5 text-green-500" />} | ||
| form={form} | ||
| /> | ||
| <CategoryCard | ||
| label="Calendar" | ||
| id="calendar" | ||
| icon={<Calendar className="h-5 w-5 text-yellow-500" />} | ||
| form={form} | ||
| /> | ||
| <CategoryCard | ||
| label="Receipts" | ||
| id="receipts" | ||
| icon={<Receipt className="h-5 w-5 text-orange-500" />} | ||
| form={form} | ||
| /> | ||
| <CategoryCard | ||
| label="Notifications" | ||
| id="notifications" | ||
| icon={<Bell className="h-5 w-5 text-red-500" />} | ||
| form={form} | ||
| /> | ||
| <CategoryCard | ||
| label="Cold Emails" | ||
| id="coldEmails" | ||
| icon={<Users className="h-5 w-5 text-indigo-500" />} | ||
| form={form} | ||
| /> | ||
| </div> | ||
|
|
||
| <div className="mt-6 flex flex-col gap-2"> | ||
| <Button type="submit" className="w-full" size="lg"> | ||
| Next | ||
| </Button> | ||
|
|
||
| <Button className="w-full" size="lg" variant="outline" asChild> | ||
| <Link href={NEXT_URL}>Skip</Link> | ||
| </Button> | ||
| </div> | ||
| </form> | ||
| </Form> | ||
| ); | ||
| } | ||
|
|
||
| function CategoryCard({ | ||
| id, | ||
| label, | ||
| icon, | ||
| form, | ||
| }: { | ||
| id: keyof CreateRulesOnboardingBody; | ||
| label: string; | ||
| icon: React.ReactNode; | ||
| form: ReturnType<typeof useForm<CreateRulesOnboardingBody>>; | ||
| }) { | ||
| return ( | ||
| <Card> | ||
| <CardContent className="flex items-center gap-4 p-4"> | ||
| {icon} | ||
| <div className="flex-1">{label}</div> | ||
| <div className="ml-auto flex items-center gap-4"> | ||
| <FormField | ||
| control={form.control} | ||
| name={id} | ||
| render={({ | ||
| field, | ||
| }: { | ||
| field: ControllerRenderProps< | ||
| CreateRulesOnboardingBody, | ||
| keyof CreateRulesOnboardingBody | ||
| >; | ||
| }) => ( | ||
| <FormItem> | ||
| <Select | ||
| onValueChange={field.onChange} | ||
| defaultValue={field.value} | ||
| > | ||
| <FormControl> | ||
| <SelectTrigger className="w-[180px]"> | ||
| <SelectValue /> | ||
| </SelectTrigger> | ||
| </FormControl> | ||
| <SelectContent> | ||
| <SelectItem value="label">Label</SelectItem> | ||
| <SelectItem value="label_archive"> | ||
| Label + Skip Inbox | ||
| </SelectItem> | ||
| <SelectItem value="none">None</SelectItem> | ||
| </SelectContent> | ||
| </Select> | ||
| </FormItem> | ||
| )} | ||
| /> | ||
| </div> | ||
| </CardContent> | ||
| </Card> | ||
| ); | ||
| } | ||
52 changes: 52 additions & 0 deletions
52
apps/web/app/(app)/automation/onboarding/completed/page.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| "use client"; | ||
|
|
||
| import Link from "next/link"; | ||
| import { Check } from "lucide-react"; | ||
| import { TypographyH3, TypographyP } from "@/components/Typography"; | ||
| import { Card } from "@/components/ui/card"; | ||
| import { Button } from "@/components/ui/button"; | ||
|
|
||
| export default function CompletedPage() { | ||
| return ( | ||
| <div> | ||
| <Card className="my-4 max-w-2xl p-6 sm:mx-4 md:mx-auto"> | ||
| <div className="text-center"> | ||
| <div className="mx-auto mb-6 flex h-12 w-12 items-center justify-center rounded-full bg-green-100"> | ||
| <Check className="h-6 w-6 text-green-600" /> | ||
| </div> | ||
|
|
||
| <TypographyH3>You're all set!</TypographyH3> | ||
|
|
||
| <div className="mt-6 space-y-4"> | ||
| <TypographyP> | ||
| We've configured your inbox with smart defaults to help you stay | ||
| organized. Your emails will be automatically categorized, and | ||
| we'll draft replies that match your writing style. | ||
| </TypographyP> | ||
|
|
||
| <TypographyP> | ||
| Want to customize further? You can create custom rules, and | ||
| fine-tune your preferences anytime. | ||
| </TypographyP> | ||
| </div> | ||
|
|
||
| <div className="mt-8 flex flex-col gap-4"> | ||
| <Button size="lg" asChild> | ||
| <Link href="/automation">Go to AI Assistant</Link> | ||
| </Button> | ||
|
|
||
| {/* <Button variant="outline" size="lg" asChild> | ||
| <Link | ||
| href="/automation/rules" | ||
| className="flex items-center gap-2" | ||
| > | ||
| <Settings className="h-4 w-4" /> | ||
| Customize Rules | ||
| </Link> | ||
| </Button> */} | ||
| </div> | ||
| </div> | ||
| </Card> | ||
| </div> | ||
| ); | ||
| } |
67 changes: 67 additions & 0 deletions
67
apps/web/app/(app)/automation/onboarding/draft-replies/page.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| "use client"; | ||
|
|
||
| import { useCallback } from "react"; | ||
| import { useRouter } from "next/navigation"; | ||
| import { Card } from "@/components/ui/card"; | ||
| import { TypographyH3, TypographyP } from "@/components/Typography"; | ||
| import { ButtonListSurvey } from "@/components/ButtonListSurvey"; | ||
| import { enableDraftRepliesAction } from "@/utils/actions/rule"; | ||
| import { isActionError } from "@/utils/error"; | ||
| import { toastError } from "@/components/Toast"; | ||
| import { ONBOARDING_COOKIE_NAME } from "@/app/(app)/automation/consts"; | ||
|
|
||
| export default function DraftRepliesPage() { | ||
| const router = useRouter(); | ||
|
|
||
| const onSetDraftReplies = useCallback( | ||
| async (value: string) => { | ||
| if (value === "yes") { | ||
| const result = await enableDraftRepliesAction({ enable: true }); | ||
|
|
||
| if (isActionError(result)) { | ||
| toastError({ | ||
| description: "There was an error enabling draft replies", | ||
| }); | ||
| } | ||
| } | ||
|
|
||
| // This sets the cookie to keep the sidebar state. | ||
| document.cookie = `${ONBOARDING_COOKIE_NAME}=true; path=/; max-age=${Number.MAX_SAFE_INTEGER}`; | ||
|
|
||
| router.push("/automation/onboarding/completed"); | ||
| }, | ||
| [router], | ||
| ); | ||
|
|
||
| return ( | ||
| <div> | ||
| <Card className="my-4 max-w-2xl p-6 sm:mx-4 md:mx-auto"> | ||
| <div className="text-center"> | ||
| <TypographyH3 className="mx-auto max-w-lg"> | ||
| Would you like AI to draft your email replies? | ||
| </TypographyH3> | ||
|
|
||
| <TypographyP className="mx-auto mt-4 max-w-sm text-muted-foreground"> | ||
| AI will match your writing style and suggest drafts in Gmail. You | ||
| control when and what to send. | ||
| </TypographyP> | ||
|
|
||
| <ButtonListSurvey | ||
| className="mt-6" | ||
| options={[ | ||
| { | ||
| label: "Yes, draft replies", | ||
| value: "yes", | ||
| }, | ||
| { | ||
| label: "No thanks", | ||
| value: "no", | ||
| }, | ||
| ]} | ||
| onClick={onSetDraftReplies} | ||
| /> | ||
| </div> | ||
| </Card> | ||
| </div> | ||
| ); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| import { Card } from "@/components/ui/card"; | ||
| import { CategoriesSetup } from "./CategoriesSetup"; | ||
|
|
||
| export default function OnboardingPage() { | ||
| return ( | ||
| <Card className="my-4 w-full max-w-2xl p-6 sm:mx-4 md:mx-auto"> | ||
| <CategoriesSetup /> | ||
| </Card> | ||
| ); | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.