Hide arboretum by default and update double quotes to single

This commit is contained in:
Strider Wilson 2025-06-02 11:41:45 -04:00
parent 894e151811
commit a4f4ae977e
9 changed files with 116 additions and 72 deletions

View File

@ -2,10 +2,10 @@ import React from 'react';
export const Header: React.FC = () => {
return (
<header className="w-full bg-white border-b border-gray-200 px-4 py-3">
<nav className="max-w-7xl mx-auto flex items-center justify-between">
<div className="flex items-center">
<h1 className="text-xl font-semibold">Your App Name</h1>
<header className='w-full bg-white border-b border-gray-200 px-4 py-3'>
<nav className='max-w-7xl mx-auto flex items-center justify-between'>
<div className='flex items-center'>
<h1 className='text-xl font-semibold'>Your App Name</h1>
</div>
{/* Add navigation items here as needed */}
</nav>

View File

@ -58,29 +58,29 @@ const ApproveChange: React.FC<ApproveChangeProps> = ({ rejectFormOpen, setReject
maxHeight: 400,
}}
placeholder="What's wrong with the changes?"
translate="no"
translate='no'
/>
</div>
<div className="flex items-center gap-2 w-full mb-2">
<div className='flex items-center gap-2 w-full mb-2'>
<input
type="checkbox"
id="share-project"
type='checkbox'
id='share-project'
checked={shareProject}
onChange={(event) => setShareProject(event.target.checked)}
className="rounded border-red-300 text-red-500 focus:ring-red-500"
/>
<label htmlFor="share-project" className="text-sm text-red-600">
<label htmlFor='share-project' className='text-sm text-red-600'>
Share with Nut team
</label>
</div>
<div className="flex items-center gap-1 w-full h-[30px] pt-2">
<div className='flex items-center gap-1 w-full h-[30px] pt-2'>
<button
onClick={() => performReject()}
className="flex-1 h-[30px] flex justify-center items-center bg-red-100 border border-red-500 text-red-500 hover:bg-red-200 hover:text-red-600 transition-colors rounded"
aria-label="Revert changes"
title="Revert changes"
className='flex-1 h-[30px] flex justify-center items-center bg-red-100 border border-red-500 text-red-500 hover:bg-red-200 hover:text-red-600 transition-colors rounded'
aria-label='Revert changes'
title='Revert changes'
>
<div className="i-ph:arrow-arc-left-bold"></div>
</button>
@ -90,22 +90,22 @@ const ApproveChange: React.FC<ApproveChangeProps> = ({ rejectFormOpen, setReject
}
return (
<div className="flex items-center gap-1 w-full h-[30px] mb-2">
<div className='flex items-center gap-1 w-full h-[30px] mb-2'>
<button
onClick={() => setRejectFormOpen(true)}
className="flex-1 h-[30px] flex justify-center items-center bg-red-100 border border-red-500 text-red-500 hover:bg-red-200 hover:text-red-600 transition-colors rounded"
aria-label="Reject change"
title="Reject change"
className='flex-1 h-[30px] flex justify-center items-center bg-red-100 border border-red-500 text-red-500 hover:bg-red-200 hover:text-red-600 transition-colors rounded'
aria-label='Reject change'
title='Reject change'
>
<div className="i-ph:thumbs-down-bold"></div>
<div className='i-ph:thumbs-down-bold'></div>
</button>
<button
onClick={onApprove}
className="flex-1 h-[30px] flex justify-center items-center bg-green-100 border border-green-500 text-green-500 hover:bg-green-200 hover:text-green-600 transition-colors rounded"
aria-label="Approve change"
title="Approve change"
className='flex-1 h-[30px] flex justify-center items-center bg-green-100 border border-green-500 text-green-500 hover:bg-green-200 hover:text-green-600 transition-colors rounded'
aria-label='Approve change'
title='Approve change'
>
<div className="i-ph:thumbs-up-bold"></div>
<div className='i-ph:thumbs-up-bold'></div>
</button>
</div>
);

View File

@ -2,7 +2,7 @@
* @ts-nocheck
* Preventing TS checks with files presented in the video for a better presentation.
*/
import React, { type RefCallback, useCallback } from 'react';
import React, { type RefCallback, useCallback, useState } from 'react';
import { ClientOnly } from 'remix-utils/client-only';
import { Menu } from '~/components/sidebar/Menu.client';
import { Workbench } from '~/components/workbench/Workbench.client';
@ -11,14 +11,13 @@ import { Messages } from '~/components/chat/Messages.client';
import { type Message } from '~/lib/persistence/message';
import * as Tooltip from '@radix-ui/react-tooltip';
import { IntroSection } from '~/components/chat/BaseChat/components/IntroSection/IntroSection';
import { SearchInput } from '~/components/chat/SearchInput/SearchInput';
import { ChatPromptContainer } from '~/components/chat/BaseChat/components/ChatPromptContainer/ChatPromptContainer';
import { useSpeechRecognition } from '~/hooks/useSpeechRecognition';
import styles from './BaseChat.module.scss';
import { ExamplePrompts } from '~/components/chat/ExamplePrompts';
import { ExampleLibraryApps } from '~/components/app-library/ExampleLibraryApps';
import type { RejectChangeData } from '~/components/chat/ApproveChange';
import { type MessageInputProps } from '~/components/chat/MessageInput/MessageInput';
import { Arboretum } from './components/Arboretum/Arboretum';
export const TEXTAREA_MIN_HEIGHT = 76;
@ -74,8 +73,8 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
ref,
) => {
const TEXTAREA_MAX_HEIGHT = chatStarted ? 400 : 200;
const [rejectFormOpen, setRejectFormOpen] = React.useState(false);
const [filterText, setFilterText] = React.useState('');
const [rejectFormOpen, setRejectFormOpen] = useState(false);
const [showArboretum, setShowArboretum] = useState(false);
const onTranscriptChange = useCallback(
(transcript: string) => {
@ -168,7 +167,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
return chatStarted ? (
<Messages
ref={messageRef}
className="flex flex-col w-full flex-1 max-w-chat pb-6 mx-auto z-1 overflow-y-auto"
className='flex flex-col w-full flex-1 max-w-chat pb-6 mx-auto z-1 overflow-y-auto'
messages={messages}
hasPendingMessage={hasPendingMessage}
pendingMessageStatus={pendingMessageStatus}
@ -199,14 +198,16 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
}
handleSendMessage(event, messageInput);
})}
<div className="text-2xl lg:text-4xl font-bold text-bolt-elements-textPrimary mt-8 mb-4 animate-fade-in text-center max-w-chat mx-auto">
Arboretum
</div>
<div className="text-bolt-elements-textSecondary text-center max-w-chat mx-auto">
Browse these auto-generated apps for a place to start
</div>
<SearchInput onSearch={setFilterText} />
<ExampleLibraryApps filterText={filterText} />
{showArboretum ? (
<Arboretum onHide={() => setShowArboretum(false)} />
) : (
<button
className='text-bolt-elements-textPrimary text-center mx-auto bg-transparent p-2 rounded-md mt-10'
onClick={() => setShowArboretum(true)}
>
Show Arboretum
</button>
)}
</>
)}
</div>

View File

@ -0,0 +1,43 @@
import { useState } from 'react';
import { SearchInput } from '~/components/chat/SearchInput/SearchInput';
import { ExampleLibraryApps } from '~/components/app-library/ExampleLibraryApps';
interface ArboretumProps {
onHide: () => void;
}
export const Arboretum: React.FC<ArboretumProps> = ({ onHide }) => {
const [filterText, setFilterText] = useState('');
return (
<div className='relative flex flex-col items-center'>
<button
onClick={onHide}
className='absolute right-4 top-30 p-2 rounded-lg bg-transparent border border-bolt-elements-textSecondary hover:bg-bolt-elements-background-depth-2 transition-colors duration-200 text-bolt-elements-textSecondary hover:text-bolt-elements-textPrimary'
aria-label='Hide Arboretum'
>
<svg
width='20'
height='20'
viewBox='0 0 24 24'
fill='none'
stroke='currentColor'
strokeWidth='2'
strokeLinecap='round'
strokeLinejoin='round'
>
<line x1='18' y1='6' x2='6' y2='18' />
<line x1='6' y1='6' x2='18' y2='18' />
</svg>
</button>
<div className='text-2xl lg:text-4xl font-bold text-bolt-elements-textPrimary mt-8 mb-4 animate-fade-in text-center max-w-chat mx-auto'>
Arboretum
</div>
<div className='text-bolt-elements-textSecondary text-center max-w-chat mx-auto'>
Browse these auto-generated apps for a place to start
</div>
<SearchInput onSearch={setFilterText} />
<ExampleLibraryApps filterText={filterText} />
</div>
);
};

View File

@ -46,28 +46,28 @@ export const ChatPromptContainer: React.FC<ChatPromptContainerProps> = ({
<svg className={classNames(styles.PromptEffectContainer)}>
<defs>
<linearGradient
id="line-gradient"
x1="20%"
y1="0%"
x2="-14%"
y2="10%"
gradientUnits="userSpaceOnUse"
gradientTransform="rotate(-45)"
id='line-gradient'
x1='20%'
y1='0%'
x2='-14%'
y2='10%'
gradientUnits='userSpaceOnUse'
gradientTransform='rotate(-45)'
>
<stop offset="0%" stopColor="#b44aff" stopOpacity="0%"></stop>
<stop offset="40%" stopColor="#b44aff" stopOpacity="80%"></stop>
<stop offset="50%" stopColor="#b44aff" stopOpacity="80%"></stop>
<stop offset="100%" stopColor="#b44aff" stopOpacity="0%"></stop>
<stop offset='0%' stopColor='#b44aff' stopOpacity='0%'></stop>
<stop offset='40%' stopColor='#b44aff' stopOpacity='80%'></stop>
<stop offset='50%' stopColor='#b44aff' stopOpacity='80%'></stop>
<stop offset='100%' stopColor='#b44aff' stopOpacity='0%'></stop>
</linearGradient>
<linearGradient id="shine-gradient">
<stop offset="0%" stopColor="white" stopOpacity="0%"></stop>
<stop offset="40%" stopColor="#ffffff" stopOpacity="80%"></stop>
<stop offset="50%" stopColor="#ffffff" stopOpacity="80%"></stop>
<stop offset="100%" stopColor="white" stopOpacity="0%"></stop>
<linearGradient id='shine-gradient'>
<stop offset='0%' stopColor='white' stopOpacity='0%'></stop>
<stop offset='40%' stopColor='#ffffff' stopOpacity='80%'></stop>
<stop offset='50%' stopColor='#ffffff' stopOpacity='80%'></stop>
<stop offset='100%' stopColor='white' stopOpacity='0%'></stop>
</linearGradient>
</defs>
<rect className={classNames(styles.PromptEffectLine)} pathLength="100" strokeLinecap="round"></rect>
<rect className={classNames(styles.PromptShine)} x="48" y="24" width="70" height="1"></rect>
<rect className={classNames(styles.PromptEffectLine)} pathLength='100' strokeLinecap='round'></rect>
<rect className={classNames(styles.PromptShine)} x='48' y='24' width='70' height='1'></rect>
</svg>
<FilePreview
files={uploadedFiles}

View File

@ -2,11 +2,11 @@ import React from 'react';
export const IntroSection: React.FC = () => {
return (
<div id="intro" className="mt-[16vh] max-w-chat mx-auto text-center px-4 lg:px-0">
<h1 className="text-3xl lg:text-6xl font-bold text-bolt-elements-textPrimary mb-4 animate-fade-in">
<div id='intro' className='mt-[16vh] max-w-chat mx-auto text-center px-4 lg:px-0'>
<h1 className='text-3xl lg:text-6xl font-bold text-bolt-elements-textPrimary mb-4 animate-fade-in'>
Get what you want
</h1>
<p className="text-md lg:text-xl mb-8 text-bolt-elements-textSecondary animate-fade-in animation-delay-200">
<p className='text-md lg:text-xl mb-8 text-bolt-elements-textSecondary animate-fade-in animation-delay-200'>
Write, test, and fix your app all from one prompt
</p>
</div>

View File

@ -34,24 +34,24 @@ export function Chat() {
<ToastContainer
closeButton={({ closeToast }) => {
return (
<button className="Toastify__close-button" onClick={closeToast}>
<div className="i-ph:x text-lg" />
<button className='Toastify__close-button' onClick={closeToast}>
<div className='i-ph:x text-lg' />
</button>
);
}}
icon={({ type }) => {
switch (type) {
case 'success': {
return <div className="i-ph:check-bold text-bolt-elements-icon-success text-2xl" />;
return <div className='i-ph:check-bold text-bolt-elements-icon-success text-2xl' />;
}
case 'error': {
return <div className="i-ph:warning-circle-bold text-bolt-elements-icon-error text-2xl" />;
return <div className='i-ph:warning-circle-bold text-bolt-elements-icon-error text-2xl' />;
}
}
return undefined;
}}
position="bottom-right"
position='bottom-right'
pauseOnFocusLoss
transition={toastAnimation}
/>

View File

@ -181,10 +181,10 @@ export const MessageInput: React.FC<MessageInputProps> = ({
/>
)}
</ClientOnly>
<div className="flex justify-between items-center text-sm p-4 pt-2">
<div className="flex gap-1 items-center">
<IconButton title="Upload file" className="transition-all" onClick={handleFileUpload}>
<div className="i-ph:paperclip text-xl"></div>
<div className='flex justify-between items-center text-sm p-4 pt-2'>
<div className='flex gap-1 items-center'>
<IconButton title='Upload file' className='transition-all' onClick={handleFileUpload}>
<div className='i-ph:paperclip text-xl'></div>
</IconButton>
<SpeechRecognitionButton
@ -195,9 +195,9 @@ export const MessageInput: React.FC<MessageInputProps> = ({
/>
</div>
{input.length > 3 ? (
<div className="text-xs text-bolt-elements-textTertiary">
Use <kbd className="kdb px-1.5 py-0.5 rounded bg-bolt-elements-background-depth-2">Shift</kbd> +{' '}
<kbd className="kdb px-1.5 py-0.5 rounded bg-bolt-elements-background-depth-2">Return</kbd> a new line
<div className='text-xs text-bolt-elements-textTertiary'>
Use <kbd className='kdb px-1.5 py-0.5 rounded bg-bolt-elements-background-depth-2'>Shift</kbd> +{' '}
<kbd className='kdb px-1.5 py-0.5 rounded bg-bolt-elements-background-depth-2'>Return</kbd> a new line
</div>
) : null}
</div>

View File

@ -7,12 +7,12 @@ interface SearchInputProps {
export const SearchInput: React.FC<SearchInputProps> = ({ onSearch }) => {
return (
<div
className="placeholder-bolt-elements-textTertiary"
className='placeholder-bolt-elements-textTertiary'
style={{ display: 'flex', justifyContent: 'center', marginBottom: '1rem' }}
>
<input
type="text"
placeholder="Search"
type='text'
placeholder='Search'
onKeyDown={(event) => {
if (event.key === 'Enter') {
onSearch(event.currentTarget.value);