diff --git a/src-web/App.tsx b/src-web/App.tsx index 4d8613a1..ee9c89bd 100644 --- a/src-web/App.tsx +++ b/src-web/App.tsx @@ -1,12 +1,12 @@ -import { FormEvent, useState } from 'react'; +import { useState } from 'react'; import { invoke } from '@tauri-apps/api/tauri'; import Editor from './components/Editor/Editor'; -import { Input } from './components/Input'; import { HStack, VStack } from './components/Stacks'; -import { Button } from './components/Button'; import { DropdownMenuRadio } from './components/Dropdown'; import { WindowDragRegion } from './components/WindowDragRegion'; import { IconButton } from './components/IconButton'; +import { Sidebar } from './components/Sidebar'; +import { UrlBar } from './components/UrlBar'; interface Response { url: string; @@ -21,24 +21,22 @@ interface Response { function App() { const [error, setError] = useState(null); const [response, setResponse] = useState(null); - const [url, setUrl] = useState('https://go-server.schier.dev/debug'); - const [loading, setLoading] = useState(false); - const [method, setMethod] = useState('get'); + const [url, setUrl] = useState('https://go-server.schier.dev/debug'); + const [method, setMethod] = useState<{ label: string; value: string }>({ + label: 'GET', + value: 'GET', + }); - async function sendRequest(e: FormEvent) { - e.preventDefault(); - setLoading(true); + async function sendRequest() { setError(null); try { - const resp = (await invoke('send_request', { method, url })) as Response; + const resp = (await invoke('send_request', { method: method.value, url })) as Response; if (resp.body.includes('')) { resp.body = resp.body.replace(//gi, ``); } - setLoading(false); setResponse(resp); } catch (err) { - setLoading(false); setError(`${err}`); } } @@ -48,9 +46,9 @@ function App() { return ( <>
- +
Send Request
- +
- - - - - - - setUrl(e.currentTarget.value)} - value={url} - placeholder="Enter a URL..." - /> - - - + + {error &&
{error}
} {response !== null && ( <> diff --git a/src-web/components/Button.tsx b/src-web/components/Button.tsx index c0a4f3a2..115c5668 100644 --- a/src-web/components/Button.tsx +++ b/src-web/components/Button.tsx @@ -5,11 +5,20 @@ import { Icon } from './Icon'; export type ButtonProps = ButtonHTMLAttributes & { color?: 'primary' | 'secondary'; size?: 'sm' | 'md'; + justify?: 'start' | 'center'; forDropdown?: boolean; }; export const Button = forwardRef(function Button( - { className, children, size = 'md', forDropdown, color, ...props }: ButtonProps, + { + className, + justify = 'center', + children, + size = 'md', + forDropdown, + color, + ...props + }: ButtonProps, ref, ) { return ( @@ -17,12 +26,15 @@ export const Button = forwardRef(function Button ref={ref} className={classnames( className, - 'rounded-md text-white flex items-center', + 'rounded-md flex items-center', + justify === 'start' && 'justify-start', + justify === 'center' && 'justify-center', size === 'md' && 'h-10 px-4', - size === 'sm' && 'h-8 px-3', - color === undefined && 'hover:bg-gray-500/[0.1] active:bg-gray-500/[0.15]', - color === 'primary' && 'bg-blue-500 hover:bg-blue-500/90 active:bg-blue-500/80', - color === 'secondary' && 'bg-violet-500 hover:bg-violet-500/90 active:bg-violet-500/80', + size === 'sm' && 'h-8 px-3 text-sm', + color === undefined && 'hover:bg-gray-500/[0.1] active:bg-gray-500/[0.15] text-gray-700', + color === 'primary' && 'bg-blue-500 hover:bg-blue-500/90 active:bg-blue-500/80 text-white', + color === 'secondary' && + 'bg-violet-500 hover:bg-violet-500/90 active:bg-violet-500/80 text-white', )} {...props} > diff --git a/src-web/components/Dropdown.tsx b/src-web/components/Dropdown.tsx index 5268adf8..a510c4dc 100644 --- a/src-web/components/Dropdown.tsx +++ b/src-web/components/Dropdown.tsx @@ -14,7 +14,7 @@ import { HotKey } from './HotKey'; interface DropdownMenuRadioProps { children: ReactNode; - onValueChange: ((value: string) => void) | null; + onValueChange: ((v: { label: string; value: string }) => void) | null; value: string; label?: string; items: { @@ -30,13 +30,20 @@ export function DropdownMenuRadio({ label, value, }: DropdownMenuRadioProps) { + const handleChange = (value: string) => { + const item = items.find((item) => item.value === value); + if (item && onValueChange) { + onValueChange(item); + } + }; + return ( {children} {label && {label}} - + {items.map((item) => ( {item.label} diff --git a/src-web/components/Icon.tsx b/src-web/components/Icon.tsx index 997e3e78..f742bf7f 100644 --- a/src-web/components/Icon.tsx +++ b/src-web/components/Icon.tsx @@ -1,34 +1,39 @@ -import { ComponentType } from 'react'; import { ArchiveIcon, CameraIcon, - ChevronDownIcon, GearIcon, HomeIcon, + PaperPlaneIcon, TriangleDownIcon, + UpdateIcon, } from '@radix-ui/react-icons'; import classnames from 'classnames'; +import { NamedExoticComponent } from 'react'; -type IconName = 'archive' | 'home' | 'camera' | 'gear' | 'triangle-down'; +type IconName = 'archive' | 'home' | 'camera' | 'gear' | 'triangle-down' | 'paper-plane' | 'update'; -const icons: Record = { +const icons: Record> = { + 'paper-plane': PaperPlaneIcon, + 'triangle-down': TriangleDownIcon, archive: ArchiveIcon, - home: HomeIcon, camera: CameraIcon, gear: GearIcon, - 'triangle-down': TriangleDownIcon, + home: HomeIcon, + update: UpdateIcon, }; export interface IconProps { icon: IconName; className?: string; + size?: 'md'; + spin?: boolean; } -export function Icon({ icon, className }: IconProps) { +export function Icon({ icon, spin, size = 'md', className }: IconProps) { const Component = icons[icon]; return ( -
- -
+ ); } diff --git a/src-web/components/IconButton.tsx b/src-web/components/IconButton.tsx index 14f87bc7..607b9c0a 100644 --- a/src-web/components/IconButton.tsx +++ b/src-web/components/IconButton.tsx @@ -2,15 +2,15 @@ import { forwardRef } from 'react'; import { Icon, IconProps } from './Icon'; import { Button, ButtonProps } from './Button'; -type Props = ButtonProps & IconProps; +type Props = Omit & ButtonProps; export const IconButton = forwardRef(function IconButton( - { icon, ...props }: Props, + { icon, spin, ...props }: Props, ref, ) { return ( ); }); diff --git a/src-web/components/Input.tsx b/src-web/components/Input.tsx index 716d50c5..c82d035f 100644 --- a/src-web/components/Input.tsx +++ b/src-web/components/Input.tsx @@ -7,12 +7,21 @@ interface Props extends InputHTMLAttributes { label: string; hideLabel?: boolean; labelClassName?: string; + containerClassName?: string; } -export function Input({ label, labelClassName, hideLabel, className, name, ...props }: Props) { +export function Input({ + label, + containerClassName, + labelClassName, + hideLabel, + className, + name, + ...props +}: Props) { const id = `input-${name}`; return ( - +