Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added apps/web/public/elements/feedback.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

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

34 changes: 16 additions & 18 deletions apps/web/src/app/(authenticated)/home/BottomSheetTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,17 +108,13 @@ export function BottomSheetTabs({ onExpandedChange }: BottomSheetTabsProps) {
return (
<div className="mx-auto w-full md:max-w-3xl rounded-t-xl overflow-clip">
<div className="overflow-hidden">
<div
className={cn(
'flex divide-x-2 divide-background items-center text-sm font-medium transition-all bg-card',
)}
>
<div className="flex divide-x-2 divide-background items-center text-sm font-medium transition-all bg-card">
<BasicTooltip content="Opt/Alt + T">
<button
type="button"
onClick={() => onTabClick('recent')}
className={cn(
'pl-4 pr-5 py-3 cursor-pointer font-semibold text-left transition-colors',
'pl-4 pr-5 py-3 cursor-pointer font-semibold text-left transition-colors text-nowrap',
activeTab === 'recent'
? 'bg-foreground text-accent-foreground dark:bg-accent-foreground dark:text-card'
: 'text-muted-foreground/80 hover:text-accent-foreground',
Expand All @@ -133,7 +129,7 @@ export function BottomSheetTabs({ onExpandedChange }: BottomSheetTabsProps) {
type="button"
onClick={() => onTabClick('pullRequests')}
className={cn(
'px-5 py-3 cursor-pointer font-semibold text-left transition-colors',
'px-5 py-3 cursor-pointer font-semibold text-left transition-colors text-nowrap',
activeTab === 'pullRequests'
? 'bg-foreground text-accent-foreground dark:bg-accent-foreground dark:text-card'
: 'text-muted-foreground/80 hover:text-accent-foreground',
Expand All @@ -143,17 +139,19 @@ export function BottomSheetTabs({ onExpandedChange }: BottomSheetTabsProps) {
</button>
</BasicTooltip>

<button
type="button"
onClick={closeSheet}
aria-label="Close bottom sheet"
className={cn(
'relative ml-auto mr-2 inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-muted-foreground/80 transition-all duration-500 delay-150 hover:text-foreground',
isExpanded ? 'top-0 opacity-100' : 'top-6 opacity-0',
)}
>
<X className="size-4" />
</button>
<div className="ml-auto flex min-w-0 items-center">
<button
type="button"
onClick={closeSheet}
aria-label="Close bottom sheet"
className={cn(
'relative mr-2 inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-muted-foreground/80 transition-all duration-500 delay-150 hover:text-foreground',
isExpanded ? 'top-0 opacity-100' : 'top-6 opacity-0',
)}
>
<X className="size-4" />
</button>
</div>
</div>

<div
Expand Down
91 changes: 91 additions & 0 deletions apps/web/src/app/(authenticated)/home/Home.client.test.tsx

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

119 changes: 119 additions & 0 deletions apps/web/src/app/(authenticated)/home/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,17 @@ import { useCreateStandardTaskRun, useRouteHomeTask } from '@/hooks/task-runs';
import {
Alert,
ArrowRight,
Button,
Calendar,
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
Loader2,
Mail,
MessageCirclePlus,
Select,
SelectContent,
SelectItem,
Expand All @@ -54,12 +64,36 @@ import {

import { OnboardingCard } from './OnboardingCard';
import { BottomSheetTabs } from './BottomSheetTabs';
import Image from 'next/image';
import { DiscordLogoIcon } from '@radix-ui/react-icons';
import {
HOME_PROMPT_PLACEHOLDERS,
normalizeHomePromptPlaceholderIndex,
} from './promptPlaceholders';

const FALLBACK_PROMPT_PLACEHOLDER = 'What do you want to do?';
const FEEDBACK_DISMISSED_STORAGE_KEY = 'roomote-home-feedback-dismissed';
const FEEDBACK_CALENDLY_URL =
'https://calendly.com/d/ctx9-f7q-6vr/roomote-feedback';
const FEEDBACK_EMAIL_URL =
'mailto:help@roomote.dev?subject=My%20thoughts%20on%20Roomote%20so%20far';
const FEEDBACK_DISCORD_URL = 'https://discord.gg/roomote';

function isFeedbackPromptDismissed(): boolean {
try {
return window.localStorage.getItem(FEEDBACK_DISMISSED_STORAGE_KEY) === '1';
} catch {
return false;
}
}

function persistFeedbackPromptDismissal(): void {
try {
window.localStorage.setItem(FEEDBACK_DISMISSED_STORAGE_KEY, '1');
} catch {
// Ignore storage failures; the prompt can still be dismissed for this session.
}
}

type RoutingFlowState = 'idle' | 'routing_pending' | 'launching';

Expand Down Expand Up @@ -147,6 +181,8 @@ export function Home({
const [selectedModelOverrideId, setSelectedModelOverrideId] =
useState<string>();
const [isBottomSheetExpanded, setIsBottomSheetExpanded] = useState(false);
const [isFeedbackPromptVisible, setIsFeedbackPromptVisible] = useState(false);
const [isFeedbackDialogOpen, setIsFeedbackDialogOpen] = useState(false);
const [isShortViewport, setIsShortViewport] = useState(false);
const [placeholderIndex, setPlaceholderIndex] = useState(() =>
normalizeHomePromptPlaceholderIndex(initialPlaceholderIndex),
Expand All @@ -167,6 +203,10 @@ export function Home({

useEffect(() => setPromptText(promptParam), [promptParam]);

useEffect(() => {
setIsFeedbackPromptVisible(!isFeedbackPromptDismissed());
}, []);

useEffect(() => {
setPlaceholderIndex(
normalizeHomePromptPlaceholderIndex(initialPlaceholderIndex),
Expand Down Expand Up @@ -714,13 +754,92 @@ export function Home({

<div className="flex flex-col md:flex-row flex-wrap md:items-center gap-2 animate-[fade-in_1s_1_750ms_backwards]">
<OnboardingCard />
{isFeedbackPromptVisible ? (
<button
type="button"
onClick={() => setIsFeedbackDialogOpen(true)}
className="inline-flex cursor-pointer items-center font-semibold whitespace-nowrap text-sm text-muted-foreground/80 hover:text-accent-foreground md:ml-auto"
>
<MessageCirclePlus className="mr-1.5 size-4 shrink-0" />
Feedback, please!
</button>
) : null}
</div>
</div>
<div className="shrink-0 pb-[env(safe-area-inset-bottom)]">
<BottomSheetTabs onExpandedChange={setIsBottomSheetExpanded} />
</div>
</div>
</div>

<Dialog
open={isFeedbackDialogOpen}
onOpenChange={setIsFeedbackDialogOpen}
>
<DialogContent size="xl">
<DialogHeader>
<DialogTitle>What do you think of Roomote so far?</DialogTitle>
<DialogDescription>
We&apos;d love to hear about your experience. Anything helps.
</DialogDescription>
</DialogHeader>

<div className="relative my-4 flex flex-col gap-2">
<Button
asChild
variant="default"
className="md:max-w-xs md:justify-start"
>
<a href={FEEDBACK_CALENDLY_URL} target="_blank" rel="noreferrer">
<Calendar className="size-3.5" />
Schedule time with the team
</a>
</Button>
<Button
asChild
variant="default"
className="md:max-w-xs md:justify-start"
>
<a href={FEEDBACK_EMAIL_URL}>
<Mail className="size-3.5" />
Email us
</a>
</Button>
<Button
asChild
variant="default"
className="md:max-w-xs md:justify-start"
>
<a href={FEEDBACK_DISCORD_URL} target="_blank" rel="noreferrer">
<DiscordLogoIcon className="size-3.5" />
Join the discord
</a>
</Button>
<Image
src="/elements/feedback.png"
alt=""
width={150}
height={150}
className="absolute -top-9 right-0 hidden size-44 md:block"
/>
</div>

<DialogFooter className="md:justify-between">
<Button
type="button"
variant="link"
size="sm"
onClick={() => {
persistFeedbackPromptDismissal();
setIsFeedbackPromptVisible(false);
}}
aria-label="Dismiss feedback prompt"
>
Don&apos;t show this again
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</FormProvider>
);
}
1 change: 1 addition & 0 deletions apps/web/src/components/system/primitives/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ export {
Maximize2,
Menu,
Megaphone,
MessageCirclePlus,
MessageCircleQuestionMark,
MessageSquareCode,
MessageSquareIcon,
Expand Down
Loading