diff --git a/bun.lock b/bun.lock index 92b608335..ecd7a16e0 100644 --- a/bun.lock +++ b/bun.lock @@ -21,16 +21,16 @@ "@opentelemetry/semantic-conventions": "^1.36.0", "@radix-ui/react-avatar": "^1.1.4", "@radix-ui/react-checkbox": "^1.3.3", - "@radix-ui/react-dialog": "^1.1.7", + "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.7", "@radix-ui/react-label": "^2.1.3", - "@radix-ui/react-popover": "^1.1.7", + "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-radio-group": "^1.3.8", "@radix-ui/react-scroll-area": "^1.2.4", "@radix-ui/react-select": "^2.1.7", "@radix-ui/react-separator": "^1.1.3", "@radix-ui/react-slider": "^1.2.4", - "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-tabs": "^1.1.12", "@radix-ui/react-toast": "^1.2.7", "@radix-ui/react-tooltip": "^1.2.0", @@ -76,9 +76,8 @@ "file-type": "^21.3.0", "geist": "^1.3.1", "immer": "^10.1.1", - "lucide-react": "^0.525.0", "micromatch": "^4.0.8", - "motion": "^12.18.1", + "motion": "^12.23.25", "nanoid": "^5.0.9", "next": "16.1.5", "next-safe-action": "^8.0.11", @@ -153,6 +152,8 @@ }, }, "overrides": { + "@nodelib/fs.scandir": "2.1.5", + "@nodelib/fs.stat": "2.0.5", "@shikijs/core": "2.3.2", "@shikijs/themes": "2.3.2", "shiki": "2.3.2", @@ -1621,7 +1622,7 @@ "fraction.js": ["fraction.js@4.3.7", "", {}, "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew=="], - "framer-motion": ["framer-motion@12.23.24", "", { "dependencies": { "motion-dom": "^12.23.23", "motion-utils": "^12.23.6", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-HMi5HRoRCTou+3fb3h9oTLyJGBxHfW+HnNE25tAXOvVx/IvwMHK0cx7IR4a2ZU6sh3IX1Z+4ts32PcYBOqka8w=="], + "framer-motion": ["framer-motion@12.23.25", "", { "dependencies": { "motion-dom": "^12.23.23", "motion-utils": "^12.23.6", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-gUHGl2e4VG66jOcH0JHhuJQr6ZNwrET9g31ZG0xdXzT0CznP7fHX4P8Bcvuc4MiUB90ysNnWX2ukHRIggkl6hQ=="], "fs-extra": ["fs-extra@4.0.3", "", { "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg=="], @@ -1871,8 +1872,6 @@ "lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], - "lucide-react": ["lucide-react@0.525.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Tm1txJ2OkymCGkvwoHt33Y2JpN5xucVq1slHcgE6Lk0WjDfjgKWor5CdVER8U6DvcfMwh4M8XxmpTiyzfmfDYQ=="], - "lz-string": ["lz-string@1.5.0", "", { "bin": { "lz-string": "bin/bin.js" } }, "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ=="], "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], @@ -1973,7 +1972,7 @@ "module-details-from-path": ["module-details-from-path@1.0.4", "", {}, "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w=="], - "motion": ["motion@12.23.24", "", { "dependencies": { "framer-motion": "^12.23.24", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-Rc5E7oe2YZ72N//S3QXGzbnXgqNrTESv8KKxABR20q2FLch9gHLo0JLyYo2hZ238bZ9Gx6cWhj9VO0IgwbMjCw=="], + "motion": ["motion@12.23.25", "", { "dependencies": { "framer-motion": "^12.23.25", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-Fk5Y1kcgxYiTYOUjmwfXQAP7tP+iGqw/on1UID9WEL/6KpzxPr9jY2169OsjgZvXJdpraKXy0orkjaCVIl5fgQ=="], "motion-dom": ["motion-dom@12.23.23", "", { "dependencies": { "motion-utils": "^12.23.6" } }, "sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA=="], diff --git a/package.json b/package.json index e24fa2a43..1694cd31e 100644 --- a/package.json +++ b/package.json @@ -62,16 +62,16 @@ "@opentelemetry/semantic-conventions": "^1.36.0", "@radix-ui/react-avatar": "^1.1.4", "@radix-ui/react-checkbox": "^1.3.3", - "@radix-ui/react-dialog": "^1.1.7", + "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.7", "@radix-ui/react-label": "^2.1.3", - "@radix-ui/react-popover": "^1.1.7", + "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-radio-group": "^1.3.8", "@radix-ui/react-scroll-area": "^1.2.4", "@radix-ui/react-select": "^2.1.7", "@radix-ui/react-separator": "^1.1.3", "@radix-ui/react-slider": "^1.2.4", - "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-tabs": "^1.1.12", "@radix-ui/react-toast": "^1.2.7", "@radix-ui/react-tooltip": "^1.2.0", @@ -117,9 +117,8 @@ "file-type": "^21.3.0", "geist": "^1.3.1", "immer": "^10.1.1", - "lucide-react": "^0.525.0", "micromatch": "^4.0.8", - "motion": "^12.18.1", + "motion": "^12.23.25", "nanoid": "^5.0.9", "next": "16.1.5", "next-safe-action": "^8.0.11", diff --git a/src/app/(auth)/auth/cli/page.tsx b/src/app/(auth)/auth/cli/page.tsx index 221daca26..b6ad3aafd 100644 --- a/src/app/(auth)/auth/cli/page.tsx +++ b/src/app/(auth)/auth/cli/page.tsx @@ -1,4 +1,3 @@ -import { CloudIcon, LaptopIcon, Link2Icon } from 'lucide-react' import { redirect } from 'next/navigation' import { Suspense } from 'react' import { AUTH_URLS, PROTECTED_URLS } from '@/configs/urls' @@ -8,6 +7,7 @@ import { createClient } from '@/core/shared/clients/supabase/server' import { encodedRedirect } from '@/lib/utils/auth' import { generateE2BUserAccessToken } from '@/lib/utils/server' import { Alert, AlertDescription, AlertTitle } from '@/ui/primitives/alert' +import { CloudIcon, LinkIcon, SystemIcon } from '@/ui/primitives/icons' // Types type CLISearchParams = Promise<{ @@ -59,13 +59,13 @@ function CLIIcons() { return (

- + - + - +

) diff --git a/src/app/(auth)/confirm/page.tsx b/src/app/(auth)/confirm/page.tsx index 07cd39f90..6bdb0c085 100644 --- a/src/app/(auth)/confirm/page.tsx +++ b/src/app/(auth)/confirm/page.tsx @@ -115,7 +115,9 @@ export default function ConfirmPage() {
diff --git a/src/app/(auth)/sign-in/page.tsx b/src/app/(auth)/sign-in/page.tsx index 7bc10651f..7faa4bf36 100644 --- a/src/app/(auth)/sign-in/page.tsx +++ b/src/app/(auth)/sign-in/page.tsx @@ -149,7 +149,10 @@ export default function Login() { - diff --git a/src/app/(auth)/sign-up/page.tsx b/src/app/(auth)/sign-up/page.tsx index e1022c484..3604c688a 100644 --- a/src/app/(auth)/sign-up/page.tsx +++ b/src/app/(auth)/sign-up/page.tsx @@ -181,7 +181,7 @@ export default function SignUp() {
diff --git a/src/app/dashboard/[teamSlug]/webhooks/page.tsx b/src/app/dashboard/[teamSlug]/webhooks/page.tsx index 11146c781..19bca5b4d 100644 --- a/src/app/dashboard/[teamSlug]/webhooks/page.tsx +++ b/src/app/dashboard/[teamSlug]/webhooks/page.tsx @@ -1,4 +1,3 @@ -import { Plus } from 'lucide-react' import { notFound } from 'next/navigation' import { INCLUDE_ARGUS } from '@/configs/flags' import WebhookAddEditDialog from '@/features/dashboard/settings/webhooks/add-edit-dialog' @@ -11,6 +10,7 @@ import { CardDescription, CardHeader, } from '@/ui/primitives/card' +import { AddIcon } from '@/ui/primitives/icons' interface WebhooksPageClientProps { params: Promise<{ @@ -43,7 +43,7 @@ export default async function WebhooksPage({ diff --git a/src/app/dashboard/unauthorized.tsx b/src/app/dashboard/unauthorized.tsx index 6a6a8fb8f..24d4c45a5 100644 --- a/src/app/dashboard/unauthorized.tsx +++ b/src/app/dashboard/unauthorized.tsx @@ -1,6 +1,5 @@ 'use client' -import { ArrowLeft, HomeIcon, ShieldX, UsersIcon } from 'lucide-react' import Link from 'next/link' import { PROTECTED_URLS } from '@/configs/urls' import { AsciiBackgroundPattern } from '@/ui/patterns' @@ -12,6 +11,12 @@ import { CardFooter, CardHeader, } from '@/ui/primitives/card' +import { + ArrowLeftIcon, + HomeIcon, + PersonsIcon, + ShieldXIcon, +} from '@/ui/primitives/icons' export default function Unauthorized() { return ( @@ -20,7 +25,7 @@ export default function Unauthorized() {
- +
403 Access denied. @@ -31,27 +36,27 @@ export default function Unauthorized() { team owner or administrator to request access.

- -
- -
diff --git a/src/configs/sidebar.ts b/src/configs/sidebar.ts index 64f6102d6..7ca6f3ed0 100644 --- a/src/configs/sidebar.ts +++ b/src/configs/sidebar.ts @@ -1,16 +1,16 @@ +import { JSX } from 'react' import { - Activity, - Box, - Container, - CreditCard, - Key, - type LucideProps, - Settings, - UserRoundCog, - Users, -} from 'lucide-react' -import type { ForwardRefExoticComponent, JSX, RefAttributes } from 'react' -import { GaugeIcon, WebhookIcon } from '@/ui/primitives/icons' + AccountSettingsIcon, + CardIcon, + GaugeIcon, + KeyIcon, + PersonsIcon, + SandboxIcon, + SettingsIcon, + TemplateIcon, + UsageIcon, + WebhookIcon, +} from '@/ui/primitives/icons' import { INCLUDE_ARGUS, INCLUDE_BILLING } from './flags' import { PROTECTED_URLS } from './urls' @@ -21,11 +21,8 @@ type SidebarNavArgs = { export type SidebarNavItem = { label: string href: (args: SidebarNavArgs) => string - icon: - | ForwardRefExoticComponent< - Omit & RefAttributes - > - | ((...args: any[]) => JSX.Element) + // eslint-disable-next-line @typescript-eslint/no-explicit-any + icon: (...args: any[]) => JSX.Element group?: string activeMatch?: string } @@ -35,13 +32,13 @@ export const SIDEBAR_MAIN_LINKS: SidebarNavItem[] = [ { label: 'Sandboxes', href: (args) => PROTECTED_URLS.SANDBOXES(args.teamSlug!), - icon: Box, + icon: SandboxIcon, activeMatch: `/dashboard/*/sandboxes/**`, }, { label: 'Templates', href: (args) => PROTECTED_URLS.TEMPLATES(args.teamSlug!), - icon: Container, + icon: TemplateIcon, activeMatch: `/dashboard/*/templates/**`, }, @@ -63,21 +60,21 @@ export const SIDEBAR_MAIN_LINKS: SidebarNavItem[] = [ { label: 'General', href: (args) => PROTECTED_URLS.GENERAL(args.teamSlug!), - icon: Settings, + icon: SettingsIcon, group: 'team', activeMatch: `/dashboard/*/general`, }, { label: 'API Keys', href: (args) => PROTECTED_URLS.KEYS(args.teamSlug!), - icon: Key, + icon: KeyIcon, group: 'team', activeMatch: `/dashboard/*/keys`, }, { label: 'Members', href: (args) => PROTECTED_URLS.MEMBERS(args.teamSlug!), - icon: Users, + icon: PersonsIcon, group: 'team', activeMatch: `/dashboard/*/members`, }, @@ -88,7 +85,7 @@ export const SIDEBAR_MAIN_LINKS: SidebarNavItem[] = [ { label: 'Usage', href: (args: SidebarNavArgs) => PROTECTED_URLS.USAGE(args.teamSlug!), - icon: Activity, + icon: UsageIcon, group: 'billing', activeMatch: `/dashboard/*/usage/**`, }, @@ -103,7 +100,7 @@ export const SIDEBAR_MAIN_LINKS: SidebarNavItem[] = [ label: 'Billing', href: (args: SidebarNavArgs) => PROTECTED_URLS.BILLING(args.teamSlug!), - icon: CreditCard, + icon: CardIcon, group: 'billing', activeMatch: `/dashboard/*/billing/**`, }, @@ -115,7 +112,7 @@ export const SIDEBAR_EXTRA_LINKS: SidebarNavItem[] = [ { label: 'Account Settings', href: () => PROTECTED_URLS.ACCOUNT_SETTINGS, - icon: UserRoundCog, + icon: AccountSettingsIcon, }, ] diff --git a/src/features/auth/form-message.tsx b/src/features/auth/form-message.tsx index 9d823936e..f79a6b4ac 100644 --- a/src/features/auth/form-message.tsx +++ b/src/features/auth/form-message.tsx @@ -1,9 +1,9 @@ 'use client' -import { AlertCircle, CheckCircle2, Info } from 'lucide-react' import { motion } from 'motion/react' import { cn } from '@/lib/utils' import { Alert, AlertDescription } from '@/ui/primitives/alert' +import { AlertIcon, InfoIcon, SuccessIcon } from '@/ui/primitives/icons' // TODO: this type is used in more places than just authentication // -> should probably be renamed / moved to a more appropriate location @@ -29,7 +29,7 @@ export function AuthFormMessage({ > {'success' in message && ( - + {decodeURIComponent(message.success!)} @@ -37,7 +37,7 @@ export function AuthFormMessage({ )} {'error' in message && ( - + {decodeURIComponent(message.error!)} @@ -45,7 +45,7 @@ export function AuthFormMessage({ )} {'message' in message && ( - + {decodeURIComponent(message.message!)} diff --git a/src/features/auth/oauth-provider-buttons.tsx b/src/features/auth/oauth-provider-buttons.tsx index a7fd7855d..4f6dc6f38 100644 --- a/src/features/auth/oauth-provider-buttons.tsx +++ b/src/features/auth/oauth-provider-buttons.tsx @@ -14,7 +14,7 @@ export function OAuthProviders() { return (
- + +
) diff --git a/src/features/dashboard/billing/addons.tsx b/src/features/dashboard/billing/addons.tsx index eb12e5f6c..70e2e123c 100644 --- a/src/features/dashboard/billing/addons.tsx +++ b/src/features/dashboard/billing/addons.tsx @@ -117,13 +117,8 @@ function AvailableAddons({ ) : ( - )} @@ -173,7 +168,7 @@ function AddonsUpgradePlaceholder() {

Upgrade to Pro to purchase add-ons for higher concurrency limits.

- ) : !showPaymentForm ? ( @@ -228,7 +226,7 @@ function PaymentAuthFailedAlert() { variant="warning" className="animate-in fade-in slide-in-from-top-2 duration-300" > - + Payment authentication failed in the last attempt. Please select a new payment method or enter the same card details again to retry. @@ -265,14 +263,14 @@ function AddonFeaturesList({
  • - +

    Raises current subscription by ${monthlyPriceCents / 100}/month

  • - +

    Pay ${(amountDueCents / 100).toFixed(2)} now for the remaining time of the month @@ -378,14 +376,12 @@ function PaymentElementForm({ {!isProcessing ? ( ) : ( diff --git a/src/features/dashboard/billing/invoices.tsx b/src/features/dashboard/billing/invoices.tsx index f561445ce..3971d032c 100644 --- a/src/features/dashboard/billing/invoices.tsx +++ b/src/features/dashboard/billing/invoices.tsx @@ -153,10 +153,10 @@ export default function BillingInvoicesTable() { {formatCurrency(invoice.cost)} - diff --git a/src/features/dashboard/billing/select-plan.tsx b/src/features/dashboard/billing/select-plan.tsx index 0b243cde9..5fd02aafa 100644 --- a/src/features/dashboard/billing/select-plan.tsx +++ b/src/features/dashboard/billing/select-plan.tsx @@ -178,7 +178,7 @@ function PlanCard({ const teamDisplayName = getTeamDisplayName(team) - const buttonVariant = isBaseTier ? 'outline' : 'default' + const buttonVariant = isBaseTier ? 'secondary' : 'primary' const buttonText = isBaseTier ? 'Downgrade' : 'Upgrade' return ( @@ -198,9 +198,7 @@ function PlanCard({ {isCurrentPlan ? ( - - Your current plan - + ) : (

    @@ -210,7 +208,7 @@ function PlanCard({ ) : ( - )} diff --git a/src/features/dashboard/layouts/header.tsx b/src/features/dashboard/layouts/header.tsx index ad20e0a95..25ac0834e 100644 --- a/src/features/dashboard/layouts/header.tsx +++ b/src/features/dashboard/layouts/header.tsx @@ -38,7 +38,7 @@ export default function DashboardLayoutHeader({ className )} > -
    +
    @@ -48,15 +48,13 @@ export default function DashboardLayoutHeader({ {copyableValue && ( )}
    - + diff --git a/src/features/dashboard/limits/limit-form.tsx b/src/features/dashboard/limits/limit-form.tsx index 2d99dfa1a..4e5bd7d35 100644 --- a/src/features/dashboard/limits/limit-form.tsx +++ b/src/features/dashboard/limits/limit-form.tsx @@ -137,7 +137,7 @@ export default function LimitForm({ className={cn('space-y-3', className)} onSubmit={form.handleSubmit(handleSave)} > -
    +
    @@ -191,10 +190,8 @@ export default function LimitForm({ diff --git a/src/features/dashboard/members/add-member-dialog.tsx b/src/features/dashboard/members/add-member-dialog.tsx index 61494b43a..cfb47eee1 100644 --- a/src/features/dashboard/members/add-member-dialog.tsx +++ b/src/features/dashboard/members/add-member-dialog.tsx @@ -1,6 +1,5 @@ 'use client' -import { Plus } from 'lucide-react' import { useState } from 'react' import { AddMemberForm } from '@/features/dashboard/members/add-member-form' import { Button } from '@/ui/primitives/button' @@ -11,6 +10,7 @@ import { DialogTitle, DialogTrigger, } from '@/ui/primitives/dialog' +import { AddIcon } from '@/ui/primitives/icons' export const AddMemberDialog = () => { const [open, setOpen] = useState(false) @@ -18,13 +18,8 @@ export const AddMemberDialog = () => { return ( - diff --git a/src/features/dashboard/members/add-member-form.tsx b/src/features/dashboard/members/add-member-form.tsx index 80d656cf2..fa64da3fd 100644 --- a/src/features/dashboard/members/add-member-form.tsx +++ b/src/features/dashboard/members/add-member-form.tsx @@ -20,7 +20,6 @@ import { FormLabel, FormMessage, } from '@/ui/primitives/form' -import { AddIcon } from '@/ui/primitives/icons' import { Input } from '@/ui/primitives/input' import { useDashboard } from '../context' @@ -73,37 +72,31 @@ export const AddMemberForm = ({ className, onSuccess }: AddMemberFormProps) => {
    ( - - Email - - - + + E-mail +
    + + + + +
    )} /> - ) diff --git a/src/features/dashboard/members/member-table-row.tsx b/src/features/dashboard/members/member-table-row.tsx index 341d68708..947160011 100644 --- a/src/features/dashboard/members/member-table-row.tsx +++ b/src/features/dashboard/members/member-table-row.tsx @@ -19,7 +19,7 @@ import { formatDate } from '@/lib/utils/formatting' import { E2BLogo } from '@/ui/brand' import { Avatar, AvatarFallback, AvatarImage } from '@/ui/primitives/avatar' import { Badge } from '@/ui/primitives/badge' -import { Button } from '@/ui/primitives/button' +import { IconButton } from '@/ui/primitives/icon-button' import { TrashIcon } from '@/ui/primitives/icons' import { TableCell, TableRow } from '@/ui/primitives/table' import { useDashboard } from '../context' @@ -157,12 +157,7 @@ const NameCell = ({ {name ?? email} {isCurrentUser ? ( - + You ) : null} @@ -270,15 +265,9 @@ const AddedCell = ({ setOpen={setRemoveDialogOpen} teamName={teamName} trigger={ - + + + } /> ) : null} diff --git a/src/features/dashboard/members/members-page-content.tsx b/src/features/dashboard/members/members-page-content.tsx index b43e7e772..66e343c4f 100644 --- a/src/features/dashboard/members/members-page-content.tsx +++ b/src/features/dashboard/members/members-page-content.tsx @@ -1,10 +1,10 @@ 'use client' -import { Search } from 'lucide-react' import { useMemo, useState } from 'react' import type { TeamMember } from '@/core/modules/teams/models' import { cn } from '@/lib/utils' import { pluralize } from '@/lib/utils/formatting' +import { SearchIcon } from '@/ui/primitives/icons' import { Input } from '@/ui/primitives/input' import { AddMemberDialog } from './add-member-dialog' import MemberTable from './member-table' @@ -37,7 +37,7 @@ const MembersPageContent = ({
    - diff --git a/src/features/dashboard/members/remove-member-dialog.tsx b/src/features/dashboard/members/remove-member-dialog.tsx index db40343c6..b8676d1d3 100644 --- a/src/features/dashboard/members/remove-member-dialog.tsx +++ b/src/features/dashboard/members/remove-member-dialog.tsx @@ -54,18 +54,16 @@ export const RemoveMemberDialog = ({
    ))} @@ -260,7 +260,7 @@ export default function ContactSupportDialog({ diff --git a/src/features/dashboard/sandbox/header/ended-at.tsx b/src/features/dashboard/sandbox/header/ended-at.tsx index acb89ce57..a807172fe 100644 --- a/src/features/dashboard/sandbox/header/ended-at.tsx +++ b/src/features/dashboard/sandbox/header/ended-at.tsx @@ -46,12 +46,7 @@ export default function EndedAt() {

    {prefix}, {timeStr}

    - +
    ) } diff --git a/src/features/dashboard/sandbox/header/kill-button.tsx b/src/features/dashboard/sandbox/header/kill-button.tsx index e8c66bcaf..f177191bf 100644 --- a/src/features/dashboard/sandbox/header/kill-button.tsx +++ b/src/features/dashboard/sandbox/header/kill-button.tsx @@ -4,7 +4,6 @@ import { useAction } from 'next-safe-action/hooks' import { useState } from 'react' import { toast } from 'sonner' import { killSandboxAction } from '@/core/server/actions/sandbox-actions' -import { cn } from '@/lib/utils/ui' import { AlertPopover } from '@/ui/alert-popover' import { Button } from '@/ui/primitives/button' import { TrashIcon } from '@/ui/primitives/icons' @@ -53,19 +52,14 @@ export default function KillButton({ className }: KillButtonProps) { description="Are you sure you want to kill this sandbox? The sandbox state will be lost and cannot be recovered." confirm="Kill Sandbox" trigger={ - } confirmProps={{ disabled: isExecuting, - loading: isExecuting, + loading: isExecuting ? 'Killing...' : undefined, }} onConfirm={handleKill} onCancel={() => setOpen(false)} diff --git a/src/features/dashboard/sandbox/header/metadata.tsx b/src/features/dashboard/sandbox/header/metadata.tsx index e9fa7cec6..708e14420 100644 --- a/src/features/dashboard/sandbox/header/metadata.tsx +++ b/src/features/dashboard/sandbox/header/metadata.tsx @@ -1,8 +1,8 @@ 'use client' -import { Braces, CircleSlash } from 'lucide-react' import { JsonPopover } from '@/ui/json-popover' import { Badge } from '@/ui/primitives/badge' +import { BlockIcon, MetadataIcon } from '@/ui/primitives/icons' import { useSandboxContext } from '../context' export default function Metadata() { @@ -11,21 +11,14 @@ export default function Metadata() { if (!sandboxInfo || sandboxInfo.state === 'killed' || !sandboxInfo.metadata) { return ( - N/A + N/A ) } return ( - - + + Metadata ) diff --git a/src/features/dashboard/sandbox/header/remaining-time.tsx b/src/features/dashboard/sandbox/header/remaining-time.tsx index d7163322d..56d61b383 100644 --- a/src/features/dashboard/sandbox/header/remaining-time.tsx +++ b/src/features/dashboard/sandbox/header/remaining-time.tsx @@ -1,11 +1,12 @@ 'use client' -import { RefreshCw, Square } from 'lucide-react' import { motion } from 'motion/react' import { useCallback, useEffect, useState } from 'react' import { cn } from '@/lib/utils' import { Badge } from '@/ui/primitives/badge' import { Button } from '@/ui/primitives/button' +import { IconButton } from '@/ui/primitives/icon-button' +import { DotIcon, RefreshIcon } from '@/ui/primitives/icons' import { useSandboxContext } from '../context' export default function RemainingTime() { @@ -45,7 +46,7 @@ export default function RemainingTime() { if (!isRunning) { return ( - Stopped + Stopped ) } @@ -54,24 +55,22 @@ export default function RemainingTime() {

    {formatted}

    - +
    ) diff --git a/src/features/dashboard/sandbox/header/started-at.tsx b/src/features/dashboard/sandbox/header/started-at.tsx index f38ef5e0a..2e6614ba1 100644 --- a/src/features/dashboard/sandbox/header/started-at.tsx +++ b/src/features/dashboard/sandbox/header/started-at.tsx @@ -31,16 +31,11 @@ export default function StartedAt() { }) return ( -
    +

    {prefix}, {timeStr}

    - +
    ) } diff --git a/src/features/dashboard/sandbox/header/status.tsx b/src/features/dashboard/sandbox/header/status.tsx index a8fe0e976..da92dd441 100644 --- a/src/features/dashboard/sandbox/header/status.tsx +++ b/src/features/dashboard/sandbox/header/status.tsx @@ -1,7 +1,7 @@ 'use client' -import { Circle, Square } from 'lucide-react' import { Badge } from '@/ui/primitives/badge' +import { DotIcon, PausedIcon } from '@/ui/primitives/icons' import { useSandboxContext } from '../context' export default function Status() { @@ -11,7 +11,7 @@ export default function Status() { if (state === 'paused') { return ( - + Paused ) @@ -19,11 +19,13 @@ export default function Status() { return ( - {isRunning ? ( - - ) : ( - - )} + {isRunning ? 'Running' : 'Stopped'} ) diff --git a/src/features/dashboard/sandbox/header/template-id.tsx b/src/features/dashboard/sandbox/header/template-id.tsx index fa254285c..0444b77f0 100644 --- a/src/features/dashboard/sandbox/header/template-id.tsx +++ b/src/features/dashboard/sandbox/header/template-id.tsx @@ -13,14 +13,9 @@ export default function TemplateId() { }, [sandboxInfo]) return ( - +

    {value}

    - +
    ) } diff --git a/src/features/dashboard/sandbox/inspect/dir.tsx b/src/features/dashboard/sandbox/inspect/dir.tsx index 6cf5ac1ac..beda65082 100644 --- a/src/features/dashboard/sandbox/inspect/dir.tsx +++ b/src/features/dashboard/sandbox/inspect/dir.tsx @@ -1,9 +1,9 @@ 'use client' -import { AlertCircle, FolderClosed, FolderOpen } from 'lucide-react' import { AnimatePresence, motion } from 'motion/react' import { cn } from '@/lib/utils' import { DataTableRow } from '@/ui/data-table' +import { AlertIcon, FolderIcon, FolderOpenIcon } from '@/ui/primitives/icons' import SandboxInspectEmptyNode from './empty-node' import type { FilesystemNode } from './filesystem/types' import { useDirectory } from './hooks/use-directory' @@ -51,9 +51,9 @@ export default function SandboxInspectDir({ dir }: SandboxInspectDirProps) { )} > {isExpanded && isLoaded ? ( - + ) : ( - + )} {hasError && ( - + {error} )} diff --git a/src/features/dashboard/sandbox/inspect/file.tsx b/src/features/dashboard/sandbox/inspect/file.tsx index f420c0506..ba8db5215 100644 --- a/src/features/dashboard/sandbox/inspect/file.tsx +++ b/src/features/dashboard/sandbox/inspect/file.tsx @@ -1,8 +1,8 @@ 'use client' -import { AlertCircle, FileIcon } from 'lucide-react' import { cn } from '@/lib/utils' import { DataTableRow } from '@/ui/data-table' +import { AlertIcon, FileIcon } from '@/ui/primitives/icons' import type { FilesystemNode } from './filesystem/types' import { useFile } from './hooks/use-file' import NodeLabel from './node-label' @@ -42,7 +42,7 @@ export default function SandboxInspectFile({ file }: SandboxInspectFileProps) { {hasError && ( - + {error} )} diff --git a/src/features/dashboard/sandbox/inspect/filesystem.tsx b/src/features/dashboard/sandbox/inspect/filesystem.tsx index 1fb84def5..9ec6fee7b 100644 --- a/src/features/dashboard/sandbox/inspect/filesystem.tsx +++ b/src/features/dashboard/sandbox/inspect/filesystem.tsx @@ -26,7 +26,7 @@ export default function SandboxInspectFilesystem({ isRunning && children.length === 0 && (!isLoaded || isLoading) return ( -
    +
    - + Incompatible template
    @@ -76,10 +80,7 @@ export default function SandboxInspectIncompatible({
    The folder should contain an{' '} - - e2b.toml - {' '} - file. + e2b.toml file.
  • @@ -87,9 +88,7 @@ export default function SandboxInspectIncompatible({

    Rebuild the template

    Use{' '} - - e2b template build - {' '} + e2b template build{' '} along with custom{' '} {' '} and any other arguments to rebuild. For example: - - -c "start.sh" - + -c "start.sh"
    @@ -120,25 +117,23 @@ export default function SandboxInspectIncompatible({ diff --git a/src/features/dashboard/sandbox/inspect/not-found.tsx b/src/features/dashboard/sandbox/inspect/not-found.tsx index 884175ba2..05648b47d 100644 --- a/src/features/dashboard/sandbox/inspect/not-found.tsx +++ b/src/features/dashboard/sandbox/inspect/not-found.tsx @@ -1,6 +1,5 @@ 'use client' -import { ArrowLeft, ArrowUp, Home, RefreshCw } from 'lucide-react' import { useParams, useRouter } from 'next/navigation' import { useCallback, useEffect, useState, useTransition } from 'react' import { PROTECTED_URLS } from '@/configs/urls' @@ -8,6 +7,12 @@ import { l, serializeErrorForLog } from '@/core/shared/clients/logger/logger' import { useSandboxInspectAnalytics } from '@/lib/hooks/use-analytics' import { cn } from '@/lib/utils' import { Button } from '@/ui/primitives/button' +import { + ArrowLeftIcon, + ArrowUpIcon, + HomeIcon, + RefreshIcon, +} from '@/ui/primitives/icons' import { useSandboxContext } from '../context' import SandboxInspectEmptyFrame from './empty' @@ -64,26 +69,26 @@ export default function SandboxInspectNotFound() { <>
    ) diff --git a/src/features/dashboard/sandbox/inspect/parent-dir-item.tsx b/src/features/dashboard/sandbox/inspect/parent-dir-item.tsx index e2f6fb17c..b7087c763 100644 --- a/src/features/dashboard/sandbox/inspect/parent-dir-item.tsx +++ b/src/features/dashboard/sandbox/inspect/parent-dir-item.tsx @@ -1,11 +1,11 @@ 'use client' -import { FolderUp } from 'lucide-react' import { useRouter } from 'next/navigation' import path from 'path' import { useTransition } from 'react' import { cn } from '@/lib/utils' import { DataTableRow } from '@/ui/data-table' +import { FolderUpIcon } from '@/ui/primitives/icons' interface SandboxInspectParentDirItemProps { rootPath: string @@ -55,7 +55,7 @@ export default function SandboxInspectParentDirItem({ } }} > - + .. ) diff --git a/src/features/dashboard/sandbox/inspect/root-path-input.tsx b/src/features/dashboard/sandbox/inspect/root-path-input.tsx index 3ee555ec3..d32d6c9aa 100644 --- a/src/features/dashboard/sandbox/inspect/root-path-input.tsx +++ b/src/features/dashboard/sandbox/inspect/root-path-input.tsx @@ -1,12 +1,12 @@ 'use client' -import { ArrowRight } from 'lucide-react' import { useRouter } from 'next/navigation' import { useEffect, useState, useTransition } from 'react' import { l, serializeErrorForLog } from '@/core/shared/clients/logger/logger' import { useSandboxInspectAnalytics } from '@/lib/hooks/use-analytics' import { cn } from '@/lib/utils' import { Button } from '@/ui/primitives/button' +import { ArrowRightIcon } from '@/ui/primitives/icons' import { Input } from '@/ui/primitives/input' import { Loader } from '@/ui/primitives/loader_d' @@ -76,12 +76,12 @@ export default function RootPathInput({ /> ) diff --git a/src/features/dashboard/sandbox/inspect/stopped-banner.tsx b/src/features/dashboard/sandbox/inspect/stopped-banner.tsx index f45fe6811..f299b5db3 100644 --- a/src/features/dashboard/sandbox/inspect/stopped-banner.tsx +++ b/src/features/dashboard/sandbox/inspect/stopped-banner.tsx @@ -1,6 +1,5 @@ 'use client' -import { AlertTriangle } from 'lucide-react' import { AnimatePresence, motion } from 'motion/react' import { useMemo } from 'react' import { cn } from '@/lib/utils' @@ -10,6 +9,7 @@ import { CardTitle, cardVariants, } from '@/ui/primitives/card' +import { WarningIcon } from '@/ui/primitives/icons' import { useSandboxContext } from '../context' import { useLastUpdated, useWatcherError } from './hooks/use-watcher' @@ -42,9 +42,9 @@ export function StoppedBanner({ rootNodeCount }: StoppedBannerProps) { 'overflow-hidden border' )} > - + - + {showWatcherError ? 'Live filesystem updates disabled' diff --git a/src/features/dashboard/sandbox/inspect/viewer-header.tsx b/src/features/dashboard/sandbox/inspect/viewer-header.tsx index 34e5e1aab..32e37fdc3 100644 --- a/src/features/dashboard/sandbox/inspect/viewer-header.tsx +++ b/src/features/dashboard/sandbox/inspect/viewer-header.tsx @@ -1,7 +1,13 @@ -import { Download, FileIcon, RefreshCcw, X } from 'lucide-react' import { motion } from 'motion/react' import CopyButton from '@/ui/copy-button' import { Button } from '@/ui/primitives/button' +import { IconButton } from '@/ui/primitives/icon-button' +import { + CloseIcon, + DownloadIcon, + FileIcon, + RefreshIcon, +} from '@/ui/primitives/icons' import type { FileContentState } from './filesystem/store' interface SandboxInspectViewerHeaderProps { @@ -27,23 +33,14 @@ export default function SandboxInspectViewerHeader({ {name} {fileContentState?.type === 'text' && ( - + )} - + + + - + - + + + ) } diff --git a/src/features/dashboard/sandbox/inspect/viewer.tsx b/src/features/dashboard/sandbox/inspect/viewer.tsx index bed8b5606..8d12123dc 100644 --- a/src/features/dashboard/sandbox/inspect/viewer.tsx +++ b/src/features/dashboard/sandbox/inspect/viewer.tsx @@ -1,7 +1,6 @@ 'use client' import { AnimatePresence } from 'framer-motion' -import { Download } from 'lucide-react' import { useEffect, useState } from 'react' import ShikiHighlighter, { type Language } from 'react-shiki' import { useShikiTheme } from '@/configs/shiki' @@ -9,6 +8,7 @@ import { useIsMobile } from '@/lib/hooks/use-mobile' import { cn } from '@/lib/utils' import { Button } from '@/ui/primitives/button' import { Drawer, DrawerContent } from '@/ui/primitives/drawer' +import { DownloadIcon } from '@/ui/primitives/icons' import { ScrollArea, ScrollBar } from '@/ui/primitives/scroll-area' import { @@ -155,9 +155,9 @@ function TextContent({ return (
    This file is empty. -
    ) @@ -215,9 +215,9 @@ function UnreadableContent({ state, onDownload }: UnreadableContentProps) { File is too large to preview ({sizeMB} MB). Limit is {maxSizeMB} MB. - ) @@ -226,9 +226,9 @@ function UnreadableContent({ state, onDownload }: UnreadableContentProps) { return (
    This file is not readable. -
    ) diff --git a/src/features/dashboard/sandbox/monitoring/components/chart-overlays.tsx b/src/features/dashboard/sandbox/monitoring/components/chart-overlays.tsx index 2c3424adc..51bc27a39 100644 --- a/src/features/dashboard/sandbox/monitoring/components/chart-overlays.tsx +++ b/src/features/dashboard/sandbox/monitoring/components/chart-overlays.tsx @@ -1,6 +1,10 @@ -import { PowerIcon, SquareIcon } from 'lucide-react' import { cn } from '@/lib/utils' -import { type AddIcon, PausedIcon, RunningIcon } from '@/ui/primitives/icons' +import { + AddIcon, + BlockIcon, + PausedIcon, + RunningIcon, +} from '@/ui/primitives/icons' import { withOpacity } from '../utils/chart-colors' import type { CrosshairMarker, @@ -20,14 +24,11 @@ const MARKER_BORDER_OPACITY = 0.12 import { formatHoverTimestamp } from '../utils/formatters' -const SANDBOX_LIFECYCLE_EVENT_ICON_MAP: Record< - string, - typeof AddIcon | typeof PowerIcon -> = { - [SANDBOX_LIFECYCLE_EVENT_CREATED]: PowerIcon, +const SANDBOX_LIFECYCLE_EVENT_ICON_MAP: Record = { + [SANDBOX_LIFECYCLE_EVENT_CREATED]: AddIcon, [SANDBOX_LIFECYCLE_EVENT_PAUSED]: PausedIcon, [SANDBOX_LIFECYCLE_EVENT_RESUMED]: RunningIcon, - [SANDBOX_LIFECYCLE_EVENT_KILLED]: SquareIcon, + [SANDBOX_LIFECYCLE_EVENT_KILLED]: BlockIcon, } function LifecycleEventOverlayGroup({ diff --git a/src/features/dashboard/sandbox/monitoring/components/monitoring-time-range-controls.tsx b/src/features/dashboard/sandbox/monitoring/components/monitoring-time-range-controls.tsx index 757019df3..fedbb7e3d 100644 --- a/src/features/dashboard/sandbox/monitoring/components/monitoring-time-range-controls.tsx +++ b/src/features/dashboard/sandbox/monitoring/components/monitoring-time-range-controls.tsx @@ -1,11 +1,11 @@ 'use client' -import { RotateCcw } from 'lucide-react' import { useCallback, useMemo, useState } from 'react' import { cn } from '@/lib/utils' import { LiveDot } from '@/ui/live' import { Button } from '@/ui/primitives/button' -import { TimeIcon } from '@/ui/primitives/icons' +import { IconButton } from '@/ui/primitives/icon-button' +import { RefreshIcon, TimeIcon } from '@/ui/primitives/icons' import { Popover, PopoverContent, @@ -189,8 +189,7 @@ export default function SandboxMonitoringTimeRangeControls({ + + ) : null} diff --git a/src/features/dashboard/sandboxes/list/open-sandbox-dialog.tsx b/src/features/dashboard/sandboxes/list/open-sandbox-dialog.tsx index 9d9efb71b..4c5bff11e 100644 --- a/src/features/dashboard/sandboxes/list/open-sandbox-dialog.tsx +++ b/src/features/dashboard/sandboxes/list/open-sandbox-dialog.tsx @@ -90,7 +90,7 @@ export function OpenSandboxDialog() { return ( - + @@ -146,8 +146,8 @@ export function OpenSandboxDialog() { } className="h-full max-md:sticky max-md:left-0 max-md:w-[calc(100svw-1.5rem)]" @@ -82,10 +82,10 @@ export const SandboxesTableBody = ({ title="No Sandboxes Yet" description="Running sandboxes can be observed here." actions={ - } diff --git a/src/features/dashboard/sandboxes/list/table-cells.tsx b/src/features/dashboard/sandboxes/list/table-cells.tsx index 0144e961e..8e6163f71 100644 --- a/src/features/dashboard/sandboxes/list/table-cells.tsx +++ b/src/features/dashboard/sandboxes/list/table-cells.tsx @@ -1,7 +1,6 @@ 'use client' import type { CellContext } from '@tanstack/react-table' -import { ArrowUpRight } from 'lucide-react' import { useRouter } from 'next/navigation' import { useMemo } from 'react' import { PROTECTED_URLS } from '@/configs/urls' @@ -10,6 +9,7 @@ import { useTemplateTableStore } from '@/features/dashboard/templates/list/store import { formatLocalLogStyleTimestamp } from '@/lib/utils/formatting' import { JsonPopover } from '@/ui/json-popover' import { Button } from '@/ui/primitives/button' +import { ExternalLinkIcon } from '@/ui/primitives/icons' import { useDashboard } from '../../context' import { useSandboxMetricsStore } from './stores/metrics-store' import type { SandboxListRow } from './table-config' @@ -120,11 +120,11 @@ export function TemplateCell({ return ( ) } diff --git a/src/features/dashboard/sandboxes/list/table-filters.tsx b/src/features/dashboard/sandboxes/list/table-filters.tsx index 4d06a2e19..b127d3a99 100644 --- a/src/features/dashboard/sandboxes/list/table-filters.tsx +++ b/src/features/dashboard/sandboxes/list/table-filters.tsx @@ -1,4 +1,3 @@ -import { ListFilter, Plus } from 'lucide-react' import * as React from 'react' import { memo, useCallback } from 'react' import { useDebounceValue } from 'usehooks-ts' @@ -20,6 +19,7 @@ import { DropdownMenuSubTrigger, DropdownMenuTrigger, } from '@/ui/primitives/dropdown-menu' +import { AddIcon, FilterIcon } from '@/ui/primitives/icons' import { Input } from '@/ui/primitives/input' import { Label } from '@/ui/primitives/label' import { Separator } from '@/ui/primitives/separator' @@ -127,11 +127,11 @@ const TemplateFilter = memo(function TemplateFilter() { className="w-full" /> @@ -221,8 +221,7 @@ const ResourcesFilter = memo(function ResourcesFilter() { /> {localValues.cpu > 0 && ( diff --git a/src/features/dashboard/sandboxes/monitoring/charts/concurrent-chart/components/range-label.tsx b/src/features/dashboard/sandboxes/monitoring/charts/concurrent-chart/components/range-label.tsx index e15bb0aaa..8bee8a034 100644 --- a/src/features/dashboard/sandboxes/monitoring/charts/concurrent-chart/components/range-label.tsx +++ b/src/features/dashboard/sandboxes/monitoring/charts/concurrent-chart/components/range-label.tsx @@ -10,13 +10,11 @@ export function RangeLabel({ label, copyValue }: RangeLabelProps) {
    @@ -24,9 +22,7 @@ export function RangeLabel({ label, copyValue }: RangeLabelProps) {
    diff --git a/src/features/dashboard/sandboxes/monitoring/charts/concurrent-chart/components/time-range-selector.tsx b/src/features/dashboard/sandboxes/monitoring/charts/concurrent-chart/components/time-range-selector.tsx index 9adb5eb50..8e7905458 100644 --- a/src/features/dashboard/sandboxes/monitoring/charts/concurrent-chart/components/time-range-selector.tsx +++ b/src/features/dashboard/sandboxes/monitoring/charts/concurrent-chart/components/time-range-selector.tsx @@ -70,10 +70,10 @@ export function TimeRangeSelector({ onValueChange={handleTimePickerChange} > diff --git a/src/features/dashboard/settings/general/info-card.tsx b/src/features/dashboard/settings/general/info-card.tsx index aaab3dd2a..19f52428b 100644 --- a/src/features/dashboard/settings/general/info-card.tsx +++ b/src/features/dashboard/settings/general/info-card.tsx @@ -31,17 +31,17 @@ export function InfoCard({ className }: InfoCardProps) {
    E-Mail {team.email} - +
    Team ID {team.id} - +
    Team Slug {team.slug} - +
    diff --git a/src/features/dashboard/settings/general/name-card.tsx b/src/features/dashboard/settings/general/name-card.tsx index b9d629b78..3a39fa5cb 100644 --- a/src/features/dashboard/settings/general/name-card.tsx +++ b/src/features/dashboard/settings/general/name-card.tsx @@ -4,6 +4,7 @@ import { zodResolver } from '@hookform/resolvers/zod' import { useHookFormOptimisticAction } from '@next-safe-action/adapter-react-hook-form/hooks' import { useQueryClient } from '@tanstack/react-query' import { AnimatePresence, motion } from 'motion/react' +import { useMemo } from 'react' import { USER_MESSAGES } from '@/configs/user-messages' import { getTransformedDefaultTeamName } from '@/core/modules/teams/utils' import { updateTeamNameAction } from '@/core/server/actions/team-actions' @@ -15,8 +16,9 @@ import { useToast, } from '@/lib/hooks/use-toast' import { exponentialSmoothing } from '@/lib/utils' +import { cn } from '@/lib/utils/ui' import { useTRPC } from '@/trpc/client' -import { Button } from '@/ui/primitives/button' +import { Button, buttonVariants } from '@/ui/primitives/button' import { Card, CardContent, @@ -32,6 +34,7 @@ import { FormMessage, } from '@/ui/primitives/form' import { Input } from '@/ui/primitives/input' +import { Loader } from '@/ui/primitives/loader' interface NameCardProps { className?: string @@ -98,6 +101,9 @@ export function NameCard({ className }: NameCardProps) { optimisticState?.team ?? team ) + const name = watch('name') + const isNameDirty = useMemo(() => name !== team.name, [name, team.name]) + return ( @@ -110,7 +116,7 @@ export function NameCard({ className }: NameCardProps) {
    )} /> - + {isExecuting ? ( +
    + {' '} + Saving... +
    + ) : ( + + )} diff --git a/src/features/dashboard/settings/general/profile-picture-card.tsx b/src/features/dashboard/settings/general/profile-picture-card.tsx index e6193d522..c41c952dc 100644 --- a/src/features/dashboard/settings/general/profile-picture-card.tsx +++ b/src/features/dashboard/settings/general/profile-picture-card.tsx @@ -2,7 +2,6 @@ import { useQueryClient } from '@tanstack/react-query' import { AnimatePresence, motion } from 'framer-motion' -import { ChevronsUp, ImagePlusIcon, Loader2, Pencil } from 'lucide-react' import { useAction } from 'next-safe-action/hooks' import { useRef, useState } from 'react' import { USER_MESSAGES } from '@/configs/user-messages' @@ -18,6 +17,12 @@ import { useTRPC } from '@/trpc/client' import { Avatar, AvatarFallback, AvatarImage } from '@/ui/primitives/avatar' import { Badge } from '@/ui/primitives/badge' import { cardVariants } from '@/ui/primitives/card' +import { + EditIcon, + PhotoIcon, + SpinnerIcon, + UploadIcon, +} from '@/ui/primitives/icons' interface ProfilePictureCardProps { className?: string @@ -113,10 +118,10 @@ export function ProfilePictureCard({ className }: ProfilePictureCardProps) { alt={`${team.name}'s profile picture`} /> - + Upload{' '} - + @@ -143,7 +148,7 @@ export function ProfilePictureCard({ className }: ProfilePictureCardProps) { exit="initial" transition={{ duration: 0.2, ease: exponentialSmoothing(5) }} > - + ) : isUploading ? ( - + ) : null} diff --git a/src/features/dashboard/settings/keys/create-api-key-dialog.tsx b/src/features/dashboard/settings/keys/create-api-key-dialog.tsx index d8f465449..d4e8deeec 100644 --- a/src/features/dashboard/settings/keys/create-api-key-dialog.tsx +++ b/src/features/dashboard/settings/keys/create-api-key-dialog.tsx @@ -124,7 +124,10 @@ const CreateApiKeyDialog: FC = ({ children }) => { /> - @@ -154,7 +157,7 @@ const CreateApiKeyDialog: FC = ({ children }) => { - + diff --git a/src/features/dashboard/settings/keys/table-row.tsx b/src/features/dashboard/settings/keys/table-row.tsx index 86f2467c4..01508dc1e 100644 --- a/src/features/dashboard/settings/keys/table-row.tsx +++ b/src/features/dashboard/settings/keys/table-row.tsx @@ -1,6 +1,5 @@ 'use client' -import { MoreHorizontal } from 'lucide-react' import { motion } from 'motion/react' import { useAction } from 'next-safe-action/hooks' import { useState } from 'react' @@ -15,7 +14,6 @@ import { } from '@/lib/hooks/use-toast' import { exponentialSmoothing } from '@/lib/utils' import { AlertDialog } from '@/ui/alert-dialog' -import { Button } from '@/ui/primitives/button' import { DropdownMenu, DropdownMenuContent, @@ -24,6 +22,8 @@ import { DropdownMenuLabel, DropdownMenuTrigger, } from '@/ui/primitives/dropdown-menu' +import { IconButton } from '@/ui/primitives/icon-button' +import { IndicatorDotsIcon } from '@/ui/primitives/icons' import { TableCell, TableRow } from '@/ui/primitives/table' interface TableRowProps { @@ -93,7 +93,7 @@ export default function ApiKeyTableRow({ onConfirm={deleteKey} confirmProps={{ disabled: isDeleting, - loading: isDeleting, + loading: isDeleting ? 'Deleting...' : undefined, }} /> @@ -123,7 +123,7 @@ export default function ApiKeyTableRow({ - + @@ -148,7 +148,7 @@ export default function ApiKeyTableRow({ onClick={() => setIsDeleteDialogOpen(true)} disabled={isDeleting} > - X Delete + Delete diff --git a/src/features/dashboard/settings/webhooks/add-edit-dialog.tsx b/src/features/dashboard/settings/webhooks/add-edit-dialog.tsx index baf9fa112..23787a632 100644 --- a/src/features/dashboard/settings/webhooks/add-edit-dialog.tsx +++ b/src/features/dashboard/settings/webhooks/add-edit-dialog.tsx @@ -2,7 +2,6 @@ import { zodResolver } from '@hookform/resolvers/zod' import { useHookFormAction } from '@next-safe-action/adapter-react-hook-form/hooks' -import { PlusIcon } from 'lucide-react' import { useState } from 'react' import { upsertWebhookAction } from '@/core/server/actions/webhooks-actions' import { UpsertWebhookSchema } from '@/core/server/functions/webhooks/schema' @@ -21,7 +20,7 @@ import { DialogTrigger, } from '@/ui/primitives/dialog' import { Form } from '@/ui/primitives/form' -import { CheckIcon } from '@/ui/primitives/icons' +import { AddIcon, CheckIcon } from '@/ui/primitives/icons' import { Loader } from '@/ui/primitives/loader' import { useDashboard } from '../../context' import { WebhookAddEditDialogSteps } from './add-edit-dialog-steps' @@ -239,7 +238,7 @@ export default function WebhookAddEditDialog({ {currentStep === 1 ? ( diff --git a/src/features/dashboard/settings/webhooks/edit-secret-dialog.tsx b/src/features/dashboard/settings/webhooks/edit-secret-dialog.tsx index cb52a6a1e..6e86312cc 100644 --- a/src/features/dashboard/settings/webhooks/edit-secret-dialog.tsx +++ b/src/features/dashboard/settings/webhooks/edit-secret-dialog.tsx @@ -175,7 +175,7 @@ export default function WebhookEditSecretDialog({ type="submit" disabled={!isSecretValid} className="w-full" - variant="outline" + variant="secondary" > Confirm diff --git a/src/features/dashboard/settings/webhooks/table-row.tsx b/src/features/dashboard/settings/webhooks/table-row.tsx index 780d5b347..839599747 100644 --- a/src/features/dashboard/settings/webhooks/table-row.tsx +++ b/src/features/dashboard/settings/webhooks/table-row.tsx @@ -1,14 +1,7 @@ 'use client' -import { - Lock, - MoreHorizontal, - Pencil, - Webhook as WebhookIcon, -} from 'lucide-react' import { useState } from 'react' import { Badge } from '@/ui/primitives/badge' -import { Button } from '@/ui/primitives/button' import { DropdownMenu, DropdownMenuContent, @@ -16,7 +9,14 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from '@/ui/primitives/dropdown-menu' -import { TrashIcon } from '@/ui/primitives/icons' +import { IconButton } from '@/ui/primitives/icon-button' +import { + EditIcon, + IndicatorDotsIcon, + PrivateIcon, + TrashIcon, + WebhookIcon, +} from '@/ui/primitives/icons' import { TableCell, TableRow } from '@/ui/primitives/table' import WebhookAddEditDialog from './add-edit-dialog' import WebhookDeleteDialog from './delete-dialog' @@ -100,20 +100,21 @@ export default function WebhookTableRow({ - + + + e.preventDefault()}> - Edit + Edit e.preventDefault()}> - Rotate Secret + Rotate + Secret diff --git a/src/features/dashboard/sidebar/blocked-banner.tsx b/src/features/dashboard/sidebar/blocked-banner.tsx index eab172897..63d9f1ff6 100644 --- a/src/features/dashboard/sidebar/blocked-banner.tsx +++ b/src/features/dashboard/sidebar/blocked-banner.tsx @@ -1,11 +1,11 @@ 'use client' -import { AlertOctagonIcon } from 'lucide-react' import { AnimatePresence, motion } from 'motion/react' import { useRouter } from 'next/navigation' import { useMemo } from 'react' import { PROTECTED_URLS } from '@/configs/urls' import { cn, exponentialSmoothing } from '@/lib/utils' +import { WarningIcon } from '@/ui/primitives/icons' import { SidebarMenuButton, SidebarMenuItem } from '@/ui/primitives/sidebar' import { useDashboard } from '../context' @@ -45,7 +45,9 @@ export default function TeamBlockageAlert({ 'bg-accent-error-bg text-accent-error-highlight border-accent-error-bg', }} onClick={handleClick} - className="h-12 bg-accent-error-bg" + className={cn('h-9 bg-accent-error-bg', { + 'cursor-default': !handleClick, + })} asChild > - +
    - + Team is Blocked {team.blockedReason && ( diff --git a/src/features/dashboard/sidebar/command.tsx b/src/features/dashboard/sidebar/command.tsx index 7c4968853..1ee3635d2 100644 --- a/src/features/dashboard/sidebar/command.tsx +++ b/src/features/dashboard/sidebar/command.tsx @@ -1,6 +1,5 @@ 'use client' -import { ChevronRight } from 'lucide-react' import { useRouter } from 'next/navigation' import { useState } from 'react' import { SIDEBAR_ALL_LINKS } from '@/configs/sidebar' @@ -53,14 +52,15 @@ export default function DashboardSidebarCommand({ tooltip="Go to..." variant={isSidebarOpen ? 'outline' : 'default'} className={cn( - 'text-fg-tertiary h-10 relative transition-all', + 'text-fg-tertiary relative transition-all pl-3 !font-normal', 'group-data-[collapsible=icon]:border-x-0 group-data-[collapsible=icon]:border-y group-data-[collapsible=icon]:!w-full group-data-[collapsible=icon]:!p-0', className )} onClick={() => setOpen(true)} > - - Go to + + > Go to + @@ -86,7 +86,7 @@ export default function DashboardSidebarContent() { > - - + {isExecuting ? ( +
    + + Creating Team... +
    + ) : ( + <> + + + + )}
    diff --git a/src/features/dashboard/sidebar/footer.tsx b/src/features/dashboard/sidebar/footer.tsx index 348251221..c5146aab1 100644 --- a/src/features/dashboard/sidebar/footer.tsx +++ b/src/features/dashboard/sidebar/footer.tsx @@ -1,6 +1,5 @@ 'use client' -import { Book, Github, LifeBuoy, MessageSquarePlus } from 'lucide-react' import Link from 'next/link' import { INCLUDE_DASHBOARD_FEEDBACK_SURVEY, @@ -8,7 +7,13 @@ import { } from '@/configs/flags' import { GITHUB_URL } from '@/configs/urls' import { cn } from '@/lib/utils' -import ExternalIcon from '@/ui/external-icon' +import { + BugIcon, + DocsIcon, + ExternalLinkIcon, + FeedbackIcon, + GithubIcon, +} from '@/ui/primitives/icons' import { SIDEBAR_TRANSITION_CLASSNAMES, SidebarFooter, @@ -35,28 +40,18 @@ export default function DashboardSidebarFooter() { target="_blank" rel="noopener noreferrer" > - + GitHub - +
    - + Documentation - + @@ -84,13 +79,12 @@ export default function DashboardSidebarFooter() { trigger={ - + Feedback } @@ -109,13 +103,12 @@ export default function DashboardSidebarFooter() { trigger={ - + Support } diff --git a/src/features/dashboard/sidebar/menu-teams.tsx b/src/features/dashboard/sidebar/menu-teams.tsx index 1a41b6159..18ed1ae54 100644 --- a/src/features/dashboard/sidebar/menu-teams.tsx +++ b/src/features/dashboard/sidebar/menu-teams.tsx @@ -61,19 +61,24 @@ export default function DashboardSidebarMenuTeams() { return ( {user?.email && ( - {user.email} + + {user.email} + )} {teams.length > 0 ? ( teams.map((team) => ( - - + + - + {team.name?.charAt(0).toUpperCase() || '?'} - + {getTeamDisplayName(team)} diff --git a/src/features/dashboard/sidebar/menu.tsx b/src/features/dashboard/sidebar/menu.tsx index 8beb64593..3d7499bda 100644 --- a/src/features/dashboard/sidebar/menu.tsx +++ b/src/features/dashboard/sidebar/menu.tsx @@ -1,6 +1,5 @@ 'use client' -import { ChevronsUpDown, LogOut, Plus, UserRoundCog } from 'lucide-react' import Link from 'next/link' import { useState } from 'react' import { PROTECTED_URLS } from '@/configs/urls' @@ -16,18 +15,18 @@ import { DropdownMenuSeparator, DropdownMenuTrigger, } from '@/ui/primitives/dropdown-menu' +import { + AccountSettingsIcon, + AddIcon, + LogoutIcon, + UnpackIcon, +} from '@/ui/primitives/icons' import { SidebarMenuButton, SidebarMenuItem } from '@/ui/primitives/sidebar' import { useDashboard } from '../context' import { CreateTeamDialog } from './create-team-dialog' import DashboardSidebarMenuTeams from './menu-teams' -interface DashboardSidebarMenuProps { - className?: string -} - -export default function DashboardSidebarMenu({ - className, -}: DashboardSidebarMenuProps) { +export default function DashboardSidebarMenu() { const { team } = useDashboard() const [createTeamOpen, setCreateTeamOpen] = useState(false) @@ -37,22 +36,14 @@ export default function DashboardSidebarMenu({ return ( <> - + - +
    - + TEAM {getTeamDisplayName(team)}
    - +
    setCreateTeamOpen(true)} > - Create New Team + Create new team - + - + - Account Settings + Account settings - Log Out + Log out diff --git a/src/features/dashboard/sidebar/sidebar-mobile.tsx b/src/features/dashboard/sidebar/sidebar-mobile.tsx index de4201c1e..69f049458 100644 --- a/src/features/dashboard/sidebar/sidebar-mobile.tsx +++ b/src/features/dashboard/sidebar/sidebar-mobile.tsx @@ -1,6 +1,6 @@ -import { Sidebar as SidebarIcon } from 'lucide-react' import { cn } from '@/lib/utils' import { Drawer, DrawerContent, DrawerTrigger } from '@/ui/primitives/drawer' +import { MenuIcon } from '@/ui/primitives/icons' import Sidebar from './sidebar' interface SidebarMobileProps { @@ -11,7 +11,7 @@ export default function SidebarMobile({ className }: SidebarMobileProps) { return ( - + diff --git a/src/features/dashboard/sidebar/toggle.tsx b/src/features/dashboard/sidebar/toggle.tsx index 75b8cb1d6..eb60de04b 100644 --- a/src/features/dashboard/sidebar/toggle.tsx +++ b/src/features/dashboard/sidebar/toggle.tsx @@ -1,12 +1,12 @@ 'use client' -import { ArrowLeftToLine, ArrowRightFromLine } from 'lucide-react' import { AnimatePresence, motion } from 'motion/react' import useKeydown from '@/lib/hooks/use-keydown' import { cn } from '@/lib/utils' import { E2BLogo } from '@/ui/brand' import ClientOnly from '@/ui/client-only' -import { Button } from '@/ui/primitives/button' +import { IconButton } from '@/ui/primitives/icon-button' +import { CollapseLeftIcon, ExpandRightIcon } from '@/ui/primitives/icons' import { useSidebar } from '@/ui/primitives/sidebar' import ShortcutTooltip from '@/ui/shortcut-tooltip' @@ -26,7 +26,7 @@ export default function DashboardSidebarToggle() {
    {/* When the sidebar is closing, we want the logo to fade out AND be removed from the DOM. */} @@ -49,18 +49,9 @@ export default function DashboardSidebarToggle() { )} - + + {isOpen ? : } +
    ) diff --git a/src/features/dashboard/templates/builds/header.tsx b/src/features/dashboard/templates/builds/header.tsx index a0d74c57e..2c783b8d8 100644 --- a/src/features/dashboard/templates/builds/header.tsx +++ b/src/features/dashboard/templates/builds/header.tsx @@ -115,11 +115,7 @@ export default function BuildsHeader() { - diff --git a/src/features/dashboard/templates/builds/table-cells.tsx b/src/features/dashboard/templates/builds/table-cells.tsx index c57e63a61..2222fe610 100644 --- a/src/features/dashboard/templates/builds/table-cells.tsx +++ b/src/features/dashboard/templates/builds/table-cells.tsx @@ -1,6 +1,5 @@ 'use client' -import { ArrowUpRight } from 'lucide-react' import { useRouter } from 'next/navigation' import { useEffect, useState } from 'react' import { PROTECTED_URLS } from '@/configs/urls' @@ -46,11 +45,9 @@ export function Template({ return ( ) } diff --git a/src/features/dashboard/templates/list/table-body.tsx b/src/features/dashboard/templates/list/table-body.tsx index 56c06eff3..4d9f74b80 100644 --- a/src/features/dashboard/templates/list/table-body.tsx +++ b/src/features/dashboard/templates/list/table-body.tsx @@ -1,11 +1,11 @@ import { flexRender, type Table } from '@tanstack/react-table' -import { ExternalLink, X } from 'lucide-react' import type { RefObject } from 'react' import type { Template } from '@/core/modules/templates/models' import { useVirtualRows } from '@/lib/hooks/use-virtual-rows' import { DataTableBody, DataTableCell, DataTableRow } from '@/ui/data-table' import Empty from '@/ui/empty' import { Button } from '@/ui/primitives/button' +import { CloseIcon, ExternalLinkIcon } from '@/ui/primitives/icons' import { useTemplateTableStore } from './stores/table-store' const ROW_HEIGHT_PX = 32 @@ -58,8 +58,8 @@ export function TemplatesTableBody({ title="No Results Found" description="No templates match your current filters" message={ - } className="h-[70%] max-md:sticky max-md:left-0 max-md:w-[calc(100svw-1.5rem)]" @@ -72,10 +72,10 @@ export function TemplatesTableBody({ title="No Templates Yet" description="Your Templates can be managed here" message={ - } diff --git a/src/features/dashboard/templates/list/table-cells.tsx b/src/features/dashboard/templates/list/table-cells.tsx index 996117eea..7892bc7f2 100644 --- a/src/features/dashboard/templates/list/table-cells.tsx +++ b/src/features/dashboard/templates/list/table-cells.tsx @@ -2,7 +2,6 @@ import { useMutation, useQueryClient } from '@tanstack/react-query' import type { CellContext } from '@tanstack/react-table' -import { Check, Copy, Lock, LockOpen, MoreVertical } from 'lucide-react' import { useMemo, useState } from 'react' import type { DefaultTemplate, Template } from '@/core/modules/templates/models' import { useClipboard } from '@/lib/hooks/use-clipboard' @@ -30,6 +29,14 @@ import { DropdownMenuSeparator, DropdownMenuTrigger, } from '@/ui/primitives/dropdown-menu' +import { IconButton } from '@/ui/primitives/icon-button' +import { + CheckIcon, + CopyIcon, + IndicatorDotsIcon, + PrivateIcon, + UnlockIcon, +} from '@/ui/primitives/icons' import { Loader } from '@/ui/primitives/loader_d' import ResourceUsage from '../../common/resource-usage' import { useDashboard } from '../../context' @@ -217,24 +224,18 @@ export function ActionsCell({ onConfirm={() => deleteTemplate()} confirmProps={{ disabled: isDeleting, - loading: isDeleting, + loading: isDeleting ? 'Deleting...' : undefined, }} /> - + {isUpdating ? : } + @@ -245,12 +246,12 @@ export function ActionsCell({ > {template.public ? ( <> - + Set Internal ) : ( <> - + Set Public )} @@ -350,9 +351,9 @@ export function TemplateNameCell({ aria-hidden="true" > {wasCopied ? ( - + ) : ( - + )}
    )} @@ -450,7 +451,7 @@ export function VisibilityCell({ size="sm" className={cn('uppercase bg-fill', !isPublic && 'pl-[3]')} > - {!isPublic && } + {!isPublic && } {isPublic ? 'Public' : 'Internal'} ) diff --git a/src/features/dashboard/templates/list/table-filters.tsx b/src/features/dashboard/templates/list/table-filters.tsx index 97c10932e..7efadf9bd 100644 --- a/src/features/dashboard/templates/list/table-filters.tsx +++ b/src/features/dashboard/templates/list/table-filters.tsx @@ -1,6 +1,5 @@ 'use client' -import { ListFilter } from 'lucide-react' import * as React from 'react' import { useDebounceValue } from 'usehooks-ts' import { cn } from '@/lib/utils' @@ -18,6 +17,7 @@ import { DropdownMenuSubTrigger, DropdownMenuTrigger, } from '@/ui/primitives/dropdown-menu' +import { FilterIcon } from '@/ui/primitives/icons' import { Label } from '@/ui/primitives/label' import { Separator } from '@/ui/primitives/separator' import { TableFilterButton } from '@/ui/table-filter-button' @@ -84,8 +84,7 @@ const ResourcesFilter = () => { /> {localValues.cpu > 0 && ( )} @@ -160,8 +154,8 @@ const TemplatesTableFilters = React.forwardRef< > - diff --git a/src/features/dashboard/usage/usage-metric-chart.tsx b/src/features/dashboard/usage/usage-metric-chart.tsx index 761333fa6..b8eb922cf 100644 --- a/src/features/dashboard/usage/usage-metric-chart.tsx +++ b/src/features/dashboard/usage/usage-metric-chart.tsx @@ -1,11 +1,9 @@ 'use client' import { DialogTitle } from '@radix-ui/react-dialog' -import { Maximize2 } from 'lucide-react' import { useState } from 'react' import { AnimatedMetricDisplay } from '@/features/dashboard/sandboxes/monitoring/charts/animated-metric-display' import { cn } from '@/lib/utils' -import { Button } from '@/ui/primitives/button' import { Card, CardContent, @@ -13,6 +11,8 @@ import { cardVariants, } from '@/ui/primitives/card' import { Dialog, DialogContent } from '@/ui/primitives/dialog' +import { IconButton } from '@/ui/primitives/icon-button' +import { UnpackIcon } from '@/ui/primitives/icons' import ComputeUsageChart from './compute-usage-chart' import { useUsageCharts } from './usage-charts-context' import { UsageTimeRangeControls } from './usage-time-range-controls' @@ -95,18 +95,17 @@ function UsageMetricChartContent({ onBrushEnd={onBrushEnd} /> {isChartHovered && !isFullscreen && ( - + + )} @@ -143,10 +142,7 @@ export function UsageMetricChart({ open={isFullscreen} onOpenChange={(open) => !open && setFullscreenMetric(null)} > - + {/* title just here to avoid accessibility dev error from radix */} {METRIC_CONFIGS[metric].title} diff --git a/src/features/dashboard/usage/usage-time-range-controls.tsx b/src/features/dashboard/usage/usage-time-range-controls.tsx index 84bcaddd8..a1e11be61 100644 --- a/src/features/dashboard/usage/usage-time-range-controls.tsx +++ b/src/features/dashboard/usage/usage-time-range-controls.tsx @@ -1,12 +1,12 @@ 'use client' -import { ChevronLeft, ChevronRight } from 'lucide-react' import { useCallback, useMemo, useState } from 'react' import { cn } from '@/lib/utils' import { findMatchingPreset } from '@/lib/utils/time-range' import { formatTimeframeAsISO8601Interval } from '@/lib/utils/timeframe' import CopyButton from '@/ui/copy-button' import { Button } from '@/ui/primitives/button' +import { ChevronLeftIcon, ChevronRightIcon } from '@/ui/primitives/icons' import { Popover, PopoverContent, @@ -134,26 +134,23 @@ export function UsageTimeRangeControls({ return (
    ) diff --git a/src/lib/hooks/use-clipboard.ts b/src/lib/hooks/use-clipboard.ts index bb9768d21..834922960 100644 --- a/src/lib/hooks/use-clipboard.ts +++ b/src/lib/hooks/use-clipboard.ts @@ -1,3 +1,5 @@ +'use client' + import { useCallback, useState } from 'react' /** diff --git a/src/styles/theme.css b/src/styles/theme.css index 2058328ae..2d05dd6cc 100644 --- a/src/styles/theme.css +++ b/src/styles/theme.css @@ -88,6 +88,7 @@ --accent-error-highlight: #ff4400; --accent-error-bg: rgba(255, 68, 0, 0.16); --accent-error-bg-large: rgba(255, 68, 0, 0.08); + --accent-error-bg-large-solid: #faebe6; --accent-secondary-error-highlight: #ff8763; --accent-secondary-error-bg: rgb(255, 135, 99, 0.16); @@ -187,6 +188,7 @@ --accent-error-highlight: #f54545; --accent-error-bg: rgba(245, 69, 69, 0.16); --accent-error-bg-large: rgba(245, 69, 69, 0.08); + --accent-error-bg-large-solid: #1d0f0f; --accent-secondary-error-highlight: #ff8763; --accent-secondary-error-bg: rgba(255, 135, 99, 0.16); @@ -297,6 +299,7 @@ --color-accent-error-highlight: var(--accent-error-highlight); --color-accent-error-bg: var(--accent-error-bg); --color-accent-error-bg-large: var(--accent-error-bg-large); + --color-accent-error-bg-large-solid: var(--accent-error-bg-large-solid); --color-accent-secondary-error-highlight: var( --accent-secondary-error-highlight diff --git a/src/ui/alert-dialog.tsx b/src/ui/alert-dialog.tsx index 41f71ecb2..b3ac378ba 100644 --- a/src/ui/alert-dialog.tsx +++ b/src/ui/alert-dialog.tsx @@ -51,7 +51,7 @@ export const AlertDialog: FC = ({ {children &&
    {children}
    } - + - diff --git a/src/ui/brand.tsx b/src/ui/brand.tsx index 5cfeeca36..5ed480f24 100644 --- a/src/ui/brand.tsx +++ b/src/ui/brand.tsx @@ -1,4 +1,4 @@ -import { cn } from '@/lib/utils' +import { cn } from '@/lib/utils/ui' import { Badge, type BadgeProps } from '@/ui/primitives/badge' export const E2BLogo = ({ diff --git a/src/ui/code-block.tsx b/src/ui/code-block.tsx index 82631ad52..b55399bd9 100644 --- a/src/ui/code-block.tsx +++ b/src/ui/code-block.tsx @@ -128,9 +128,7 @@ export const CodeBlock = forwardRef( ) : ( allowCopy && ( ) diff --git a/src/ui/copy-button-inline.tsx b/src/ui/copy-button-inline.tsx index 303a06f45..12e1154a6 100644 --- a/src/ui/copy-button-inline.tsx +++ b/src/ui/copy-button-inline.tsx @@ -1,6 +1,7 @@ import { useRef, useState } from 'react' import { useClipboard } from '@/lib/hooks/use-clipboard' import { cn } from '@/lib/utils/ui' +import { CheckIcon, CopyIcon } from '@/ui/primitives/icons' export default function CopyButtonInline({ value, @@ -11,33 +12,35 @@ export default function CopyButtonInline({ children: React.ReactNode className?: string }) { - const [wasCopied, copy] = useClipboard() - const buttonRef = useRef(null) - const [capturedWidth, setCapturedWidth] = useState(null) + const [wasCopied, copy] = useClipboard(2000) const handleClick = (e: React.MouseEvent) => { e.stopPropagation() - if (buttonRef.current && !wasCopied) { - setCapturedWidth(buttonRef.current.offsetWidth) - } copy(value) } return ( - {wasCopied ? 'Copied!' : children} + {children} + ) } diff --git a/src/ui/copy-button.tsx b/src/ui/copy-button.tsx index af27dad71..825b7e346 100644 --- a/src/ui/copy-button.tsx +++ b/src/ui/copy-button.tsx @@ -1,40 +1,52 @@ 'use client' -import { CheckIcon } from 'lucide-react' -import type { FC } from 'react' +import { AnimatePresence, motion } from 'motion/react' +import { FC } from 'react' import { useClipboard } from '@/lib/hooks/use-clipboard' -import { Button, type ButtonProps } from '@/ui/primitives/button' -import { CopyIcon } from './primitives/icons' +import { EASE_APPEAR } from '@/lib/utils/ui' +import { IconButton, IconButtonProps } from '@/ui/primitives/icon-button' +import { CheckIcon, CopyIcon } from '@/ui/primitives/icons' -interface CopyButtonProps extends ButtonProps { +interface CopyButtonProps extends IconButtonProps { value: string onCopy?: () => void } -const CopyButton: FC = ({ - value, - onCopy, - onClick, - ...props -}) => { - const [wasCopied, copy] = useClipboard() - - const handleClick = (e: React.MouseEvent) => { - e.stopPropagation() - e.preventDefault() - copy(value) - onCopy?.() - onClick?.(e) - } +const CopyButton: FC = ({ value, onCopy, ...props }) => { + const [wasCopied, copy] = useClipboard(1000) return ( - + { + copy(value) + onCopy?.() + }} + {...props} + > + + {wasCopied ? ( + + + + ) : ( + + + + )} + + ) } diff --git a/src/ui/data-table.tsx b/src/ui/data-table.tsx index 7059a12bd..d317e4943 100644 --- a/src/ui/data-table.tsx +++ b/src/ui/data-table.tsx @@ -1,12 +1,8 @@ import type { Cell, Header } from '@tanstack/react-table' -import { - ArrowDownWideNarrow, - ArrowUpDown, - ArrowUpNarrowWide, -} from 'lucide-react' import * as React from 'react' import { cn } from '@/lib/utils' import { Button } from '@/ui/primitives/button' +import { SortAscIcon, SortDescIcon } from '@/ui/primitives/icons' import { Select, SelectContent, @@ -73,14 +69,14 @@ function DataTableHead({ {sorting === undefined ? ( // Show the arrow for the next state based on sortDescFirst header.column.columnDef.sortDescFirst ? ( - + ) : ( - + ) ) : sorting ? ( - + ) : ( - + )} )} @@ -179,7 +175,6 @@ const DataTable = React.forwardRef( className={cn( // Base table styles from table.tsx 'w-full caption-bottom', - 'font-mono', // Div table styles 'w-fit', className @@ -265,32 +260,32 @@ function DataTablePagination({
    diff --git a/src/ui/error-indicator.tsx b/src/ui/error-indicator.tsx index 22542bd59..cf40fc404 100644 --- a/src/ui/error-indicator.tsx +++ b/src/ui/error-indicator.tsx @@ -1,6 +1,5 @@ 'use client' -import { RefreshCcw } from 'lucide-react' import { useRouter } from 'next/navigation' import { useTransition } from 'react' import { cn } from '@/lib/utils' @@ -13,6 +12,7 @@ import { CardHeader, CardTitle, } from './primitives/card' +import { RefreshIcon } from './primitives/icons' interface ErrorIndicatorProps { title?: string @@ -50,12 +50,12 @@ export function ErrorIndicator({ )} diff --git a/src/ui/error-tooltip.tsx b/src/ui/error-tooltip.tsx index 42e6eea6e..30f7fb166 100644 --- a/src/ui/error-tooltip.tsx +++ b/src/ui/error-tooltip.tsx @@ -1,4 +1,4 @@ -import { AlertTriangle } from 'lucide-react' +import { WarningIcon } from './primitives/icons' import { Tooltip, TooltipContent, @@ -17,11 +17,11 @@ export default function ErrorTooltip({ children, trigger }: ErrorTooltipProps) { {trigger || ( - + )} - - + + {children} diff --git a/src/ui/external-icon.tsx b/src/ui/external-icon.tsx index 840268e2f..3f846ef15 100644 --- a/src/ui/external-icon.tsx +++ b/src/ui/external-icon.tsx @@ -1,5 +1,5 @@ -import { ChevronRight } from 'lucide-react' import { cn } from '@/lib/utils' +import { ChevronRightIcon } from './primitives/icons' interface ExternalIconProps { className?: string @@ -7,7 +7,7 @@ interface ExternalIconProps { export default function ExternalIcon({ className }: ExternalIconProps) { return ( - & { - icon?: LucideIcon + icon?: Icon }): React.ReactElement { return (
    {Icon ? ( ) : ( - + )}
    ) diff --git a/src/ui/json-popover.tsx b/src/ui/json-popover.tsx index 24192ab5b..dc96d9330 100644 --- a/src/ui/json-popover.tsx +++ b/src/ui/json-popover.tsx @@ -33,10 +33,10 @@ export function JsonPopover({ -
    diff --git a/src/ui/number-input.tsx b/src/ui/number-input.tsx index 73c72fa34..881678e43 100644 --- a/src/ui/number-input.tsx +++ b/src/ui/number-input.tsx @@ -1,9 +1,9 @@ 'use client' -import { ChevronDown, ChevronUp } from 'lucide-react' import * as React from 'react' import { cn } from '@/lib/utils' -import { Button } from './primitives/button' +import { IconButton } from './primitives/icon-button' +import { ChevronDownIcon, ChevronUpIcon } from './primitives/icons' import { Input } from './primitives/input' export interface NumberInputProps @@ -97,34 +97,26 @@ export function NumberInput({ return (
    - - +
    - + - {index > 0 && '+'} + {index > 0 && ' '} {formattedKey} ) diff --git a/src/ui/primitives/loader.tsx b/src/ui/primitives/loader.tsx index 0fbb58cb5..f2e0f5c21 100644 --- a/src/ui/primitives/loader.tsx +++ b/src/ui/primitives/loader.tsx @@ -1,3 +1,5 @@ +'use client' + import * as React from 'react' import styled, { css } from 'styled-components' @@ -62,7 +64,7 @@ const StyledLoader = styled.div` ` const Loader = React.forwardRef( - ({ className, variant = 'square', size = 'md', ...props }, ref) => { + ({ className, variant = 'slash', size = 'md', ...props }, ref) => { return ( <>