Order Confirmation
blockcommercePost-purchase order confirmation & tracking page featuring a success banner with emerald checkmark halo, 4-step shipment progress bar with pulsing active state, itemized order breakdown, and customer delivery & payment cards.
Installation
$pnpm dlx shadcn-svelte@latest add https://uipkge.dev/r/svelte/order-confirmation.json$npx shadcn-svelte@latest add https://uipkge.dev/r/svelte/order-confirmation.json$yarn dlx shadcn-svelte@latest add https://uipkge.dev/r/svelte/order-confirmation.json$bunx shadcn-svelte@latest add https://uipkge.dev/r/svelte/order-confirmation.jsonManifest:
https://uipkge.dev/r/svelte/order-confirmation.jsonInstalls to:src/lib/components/blocks/order-confirmation/Variants
Loading interactive previews…
Loading interactive previews…
npm dependencies
Files installed (1)
src/lib/components/blocks/order-confirmation/OrderConfirmation.svelte16.8 kB
<script lang="ts" module> export interface OrderItem { id: string name: string variant: string quantity: number price: string image: string } export interface TrackingStep { id: string title: string date: string status: 'completed' | 'current' | 'upcoming' description: string } export interface OrderConfirmationProps { class?: string } </script> <script lang="ts"> import { Check, CheckCircle2, CreditCard, Download, ExternalLink, HelpCircle, Mail, MapPin, MessageSquare, Package, Truck, } from '@lucide/svelte' import { Badge } from '$lib/components/ui/badge' import { Button } from '$lib/components/ui/button' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '$lib/components/ui/card' import { Separator } from '$lib/components/ui/separator' import { cn } from '$lib/utils' let { class: className }: OrderConfirmationProps = $props() const orderItems: OrderItem[] = [ { id: 'item-1', name: 'Studio Wireless Noise-Canceling Headphones', variant: 'Space Gray • Over-Ear', quantity: 1, price: '$179.00', image: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=160&auto=format&fit=crop&q=80', }, { id: 'item-2', name: 'Braided USB-C Fast Charging Cable (2m)', variant: 'Midnight Black • 100W PD', quantity: 2, price: '$38.00', image: 'https://images.unsplash.com/photo-1546868871-7041f2a55e12?w=160&auto=format&fit=crop&q=80', }, { id: 'item-3', name: 'Magnetic Aluminum Desk Stand', variant: 'Silver • Anodized Aluminum', quantity: 1, price: '$35.00', image: 'https://images.unsplash.com/photo-1586105251261-72a756497a11?w=160&auto=format&fit=crop&q=80', }, ] const trackingSteps: TrackingStep[] = [ { id: 'step-1', title: 'Order Placed', date: 'Aug 21, 2026 • 10:42 AM', status: 'completed', description: 'Payment authorized & order confirmed', }, { id: 'step-2', title: 'Processing', date: 'Aug 22, 2026 • 02:15 PM', status: 'completed', description: 'Item picked & packed at warehouse', }, { id: 'step-3', title: 'Shipped', date: 'Aug 23, 2026 • 09:30 AM', status: 'current', description: 'In transit via FedEx Priority • Chicago, IL', }, { id: 'step-4', title: 'Delivered', date: 'Est. Aug 27, 2026', status: 'upcoming', description: 'Estimated delivery to front door', }, ] </script> <div data-slot="order-confirmation" class={cn('w-full space-y-6', className)}> <!-- Success Banner Card --> <Card class="border shadow-xs"> <CardContent class="flex flex-col items-center p-6 text-center sm:p-10"> <div class="bg-success/10 text-success ring-success/10 text-success relative flex size-16 items-center justify-center rounded-full ring-8 sm:size-20" > <CheckCircle2 class="size-8 sm:size-10" aria-hidden="true" /> </div> <div class="mt-6 max-w-xl space-y-2"> <div class="border-success/20 bg-success/10 text-success inline-flex items-center gap-2 rounded-full border px-3 py-1 text-xs font-medium" > <span class="bg-success size-1.5 rounded-full"></span> Order Confirmed </div> <h1 class="text-foreground text-2xl font-bold tracking-tight sm:text-3xl">Thank you for your order!</h1> <p class="text-muted-foreground text-sm sm:text-base"> We've received your order <span class="text-foreground font-mono font-semibold">#ORD-92841</span> and sent a confirmation email to <span class="text-foreground font-medium">customer@example.com</span>. </p> </div> <div class="mt-8 flex flex-wrap items-center justify-center gap-3"> <Button class="gap-2 shadow-xs"> <ExternalLink class="size-4" aria-hidden="true" /> Track Shipment </Button> <Button aria-label="Download attachment" variant="outline" class="gap-2 shadow-xs"> <Download class="size-4" aria-hidden="true" /> Download Receipt </Button> <Button variant="ghost" class="text-muted-foreground hover:text-foreground"> Continue Shopping </Button> </div> </CardContent> </Card> <!-- Tracking Stepper Card --> <Card class="border shadow-xs"> <CardHeader class="flex flex-col gap-3 pb-4 sm:flex-row sm:items-center sm:justify-between"> <div class="space-y-1"> <div class="flex items-center gap-2"> <Truck class="text-primary size-4" aria-hidden="true" /> <CardTitle class="text-base font-semibold">Shipment Progress</CardTitle> <Badge variant="secondary" class="bg-primary/10 text-primary text-xs font-medium">In Transit</Badge> </div> <p class="text-muted-foreground text-xs"> Carrier: <span class="text-foreground font-medium">FedEx Priority</span> • Tracking: <span class="text-foreground font-mono font-medium">#FX-9821734910</span> </p> </div> <div class="border-border/80 bg-muted/40 rounded-lg border px-3 py-1.5 text-xs"> <span class="text-muted-foreground">Estimated Delivery:</span> <span class="text-foreground ml-1 font-semibold">Thursday, Aug 27, 2026</span> </div> </CardHeader> <CardContent class="pt-4"> <!-- Desktop Stepper (md+) --> <div class="hidden md:block"> <div class="grid grid-cols-4 gap-4"> {#each trackingSteps as step, idx (step.id)} <div class="relative flex flex-col"> <div class="relative flex items-center"> <!-- Connecting Line before current step --> {#if idx > 0} <div class="absolute top-1/2 right-1/2 -z-0 h-0.5 w-full -translate-y-1/2 {step.status === 'upcoming' ? 'bg-muted' : 'bg-primary'}" ></div> {/if} <!-- Connecting Line after current step --> {#if idx < trackingSteps.length - 1} <div class="absolute top-1/2 left-1/2 -z-0 h-0.5 w-full -translate-y-1/2 {trackingSteps[idx + 1].status === 'upcoming' ? 'bg-muted' : 'bg-primary'}" ></div> {/if} <!-- Step Indicator Circle --> <div class="relative z-10 mx-auto flex items-center justify-center"> {#if step.status === 'completed'} <div class="bg-primary text-primary-foreground ring-background flex size-8 items-center justify-center rounded-full ring-4" > <Check class="size-4" aria-hidden="true" /> </div> {:else if step.status === 'current'} <div class="border-primary bg-background text-primary ring-background flex size-8 items-center justify-center rounded-full border-2 ring-4" > <span class="relative flex size-2.5"> <span class="bg-primary absolute inline-flex h-full w-full rounded-full opacity-75"></span> <span class="bg-primary relative inline-flex size-2.5 rounded-full"></span> </span> </div> {:else} <div class="border-muted-foreground/30 bg-muted/40 text-muted-foreground ring-background flex size-8 items-center justify-center rounded-full border-2 ring-4" > <Package class="size-3.5" aria-hidden="true" /> </div> {/if} </div> </div> <!-- Step Info --> <div class="mt-3 text-center"> <p class="text-sm font-semibold {step.status === 'upcoming' ? 'text-muted-foreground' : 'text-foreground'}" > {step.title} </p> <p class="text-muted-foreground mt-0.5 text-xs tabular-nums">{step.date}</p> <p class="text-muted-foreground/80 mt-0.5 text-xs">{step.description}</p> </div> </div> {/each} </div> </div> <!-- Mobile Stepper (< md) --> <div class="space-y-4 md:hidden"> {#each trackingSteps as step, idx (step.id)} <div class="flex items-start gap-3"> <div class="flex flex-col items-center"> {#if step.status === 'completed'} <div class="bg-primary text-primary-foreground flex size-7 shrink-0 items-center justify-center rounded-full" > <Check class="size-3.5" aria-hidden="true" /> </div> {:else if step.status === 'current'} <div class="border-primary bg-background text-primary flex size-7 shrink-0 items-center justify-center rounded-full border-2" > <span class="relative flex size-2"> <span class="bg-primary absolute inline-flex h-full w-full rounded-full opacity-75"></span> <span class="bg-primary relative inline-flex size-2 rounded-full"></span> </span> </div> {:else} <div class="border-muted-foreground/30 bg-muted/40 text-muted-foreground flex size-7 shrink-0 items-center justify-center rounded-full border-2" > <Package class="size-3" aria-hidden="true" /> </div> {/if} {#if idx < trackingSteps.length - 1} <div class="mt-1 h-8 w-0.5 {trackingSteps[idx + 1].status === 'upcoming' ? 'bg-muted' : 'bg-primary'}" ></div> {/if} </div> <div class="min-w-0 flex-1 pt-0.5 pb-2"> <div class="flex items-center justify-between gap-2"> <p class="text-sm font-semibold {step.status === 'upcoming' ? 'text-muted-foreground' : 'text-foreground'}" > {step.title} </p> <span class="text-muted-foreground text-xs tabular-nums">{step.date}</span> </div> <p class="text-muted-foreground mt-0.5 text-xs">{step.description}</p> </div> </div> {/each} </div> </CardContent> </Card> <!-- 2-Column Details Grid --> <div class="grid grid-cols-1 gap-6 lg:grid-cols-12"> <!-- Left Column: Itemized Order Summary --> <div class="lg:col-span-7"> <Card class="border shadow-xs"> <CardHeader class="pb-4"> <CardTitle class="text-base font-semibold">Order Summary</CardTitle> <CardDescription>3 items in shipment</CardDescription> </CardHeader> <CardContent class="space-y-6"> <!-- Items list --> <div class="space-y-4"> {#each orderItems as item (item.id)} <div class="flex items-center gap-4"> <div class="border-border bg-muted/40 relative size-16 shrink-0 overflow-hidden rounded-lg border"> <img src={item.image} alt={item.name} class="h-full w-full object-cover" /> </div> <div class="min-w-0 flex-1"> <p class="text-foreground truncate text-sm font-medium">{item.name}</p> <p class="text-muted-foreground text-xs">{item.variant}</p> <p class="text-muted-foreground mt-1 text-xs">Qty: {item.quantity}</p> </div> <div class="text-right"> <p class="text-foreground text-sm font-semibold tabular-nums">{item.price}</p> </div> </div> {/each} </div> <Separator /> <!-- Cost breakdown --> <div class="space-y-2 text-sm"> <div class="flex items-center justify-between"> <span class="text-muted-foreground">Subtotal</span> <span class="text-foreground font-medium tabular-nums">$252.00</span> </div> <div class="flex items-center justify-between"> <span class="text-muted-foreground">Shipping (FedEx Priority)</span> <span class="text-success text-success font-medium tabular-nums">Free</span> </div> <div class="flex items-center justify-between"> <span class="text-muted-foreground">Estimated Tax</span> <span class="text-foreground font-medium tabular-nums">$12.50</span> </div> </div> <Separator /> <!-- Total --> <div class="flex items-center justify-between"> <span class="text-foreground text-base font-semibold">Total</span> <span class="text-foreground text-xl font-bold tabular-nums sm:text-2xl">$264.50</span> </div> </CardContent> </Card> </div> <!-- Right Column: Customer & Delivery Details --> <div class="space-y-6 lg:col-span-5"> <!-- Shipping Address Card --> <Card class="border shadow-xs"> <CardHeader class="pb-3"> <div class="flex items-center gap-2"> <MapPin class="text-muted-foreground size-4" aria-hidden="true" /> <CardTitle class="text-base font-semibold">Shipping Address</CardTitle> </div> </CardHeader> <CardContent class="space-y-3 text-sm"> <div class="space-y-0.5"> <p class="text-foreground font-medium">Alex Morgan</p> <p class="text-muted-foreground">742 Evergreen Terrace, Suite 4B</p> <p class="text-muted-foreground">Springfield, OR 97477</p> <p class="text-muted-foreground">United States</p> <p class="text-muted-foreground mt-1 text-xs">+1 (555) 234-5678</p> </div> <div class="border-border bg-muted/30 rounded-md border p-2.5 text-xs"> <span class="text-muted-foreground">Delivery Method:</span> <span class="text-foreground ml-1 font-medium">FedEx Priority Express</span> </div> </CardContent> </Card> <!-- Payment Method Card --> <Card class="border shadow-xs"> <CardHeader class="pb-3"> <div class="flex items-center gap-2"> <CreditCard class="text-muted-foreground size-4" aria-hidden="true" /> <CardTitle class="text-base font-semibold">Payment Method</CardTitle> </div> </CardHeader> <CardContent class="space-y-3 text-sm"> <div class="flex items-center justify-between"> <div class="flex items-center gap-2.5"> <div class="border-border bg-muted/40 text-foreground flex h-7 w-11 items-center justify-center rounded border font-mono text-xs font-bold" > VISA </div> <div> <p class="text-foreground text-sm font-medium">Visa ending in 4242</p> <p class="text-muted-foreground text-xs">Expires 08/29</p> </div> </div> <Badge variant="secondary" class="bg-success/10 text-success">Paid</Badge> </div> <p class="text-muted-foreground text-xs">Billing address matches shipping address</p> </CardContent> </Card> <!-- Need Help Card --> <Card class="border shadow-xs"> <CardHeader class="pb-3"> <div class="flex items-center gap-2"> <HelpCircle class="text-muted-foreground size-4" aria-hidden="true" /> <CardTitle class="text-base font-semibold">Need Help?</CardTitle> </div> </CardHeader> <CardContent class="space-y-3 text-sm"> <p class="text-muted-foreground text-xs"> Questions about your order? Chat with support or email support@example.com. </p> <div class="space-y-2 pt-1"> <Button variant="outline" size="sm" class="w-full justify-start gap-2 text-xs shadow-xs"> <MessageSquare class="size-3.5" aria-hidden="true" /> Chat with Support </Button> <Button variant="ghost" size="sm" class="text-muted-foreground hover:text-foreground w-full justify-start gap-2 text-xs" > <Mail class="size-3.5" aria-hidden="true" /> support@example.com </Button> </div> </CardContent> </Card> </div> </div> </div>
Raw manifest:https://uipkge.dev/r/svelte/order-confirmation.json