import type { Meta, StoryObj } from "@storybook/react"; import { useState } from "react"; import { LinkShortener } from "./link-shortener"; import type { ShortenedLink } from "./types"; const meta: Meta = { title: "Widgets/LinkShortener", component: LinkShortener, parameters: { layout: "padded", }, tags: ["autodocs"], argTypes: { showLinkList: { control: "boolean" }, }, decorators: [ (Story) => (
), ], }; export default meta; type Story = StoryObj; // Sample links for stories const sampleLinks: ShortenedLink[] = [ { id: "1", originalUrl: "https://example.com.ai/very/long/url/that/needs/shortening", shortCode: "abc123", shortUrl: "https://short.link/abc123", title: "Marketing Campaign", clicks: 1234, createdAt: new Date("2024-01-15"), }, { id: "2", originalUrl: "https://docs.example.com.ai/api/v2/reference/endpoints", shortCode: "docs-api", shortUrl: "https://short.link/docs-api", title: "API Documentation", clicks: 567, createdAt: new Date("2024-01-10"), }, { id: "3", originalUrl: "https://blog.example.com.ai/posts/2024/how-to-build-apps", shortCode: "blog24", shortUrl: "https://short.link/blog24", clicks: 89, createdAt: new Date("2024-01-05"), }, ]; // Wrapper with state management function LinkShortenerWithState( props: React.ComponentProps, ) { const [links, setLinks] = useState(props.links || []); const handleCreate = async (link: ShortenedLink) => { setLinks((prev) => [link, ...prev]); props.onCreate?.(link); }; const handleDelete = async (linkId: string) => { setLinks((prev) => prev.filter((l) => l.id !== linkId)); props.onDelete?.(linkId); }; return ( ); } // ============================================================================= // DEFAULT // ============================================================================= export const Default: Story = { render: (args) => , args: { baseUrl: "https://short.link", }, }; // ============================================================================= // WITH EXISTING LINKS // ============================================================================= export const WithLinks: Story = { name: "With Existing Links", render: (args) => , args: { baseUrl: "https://short.link", links: sampleLinks, }, }; // ============================================================================= // CREATE ONLY (NO LIST) // ============================================================================= export const CreateOnly: Story = { name: "Create Only (No List)", render: (args) => , args: { baseUrl: "https://short.link", showLinkList: false, }, }; // ============================================================================= // CUSTOM BASE URL // ============================================================================= export const CustomBaseUrl: Story = { name: "Custom Base URL", render: (args) => , args: { baseUrl: "https://myapp.io/l", links: [], }, }; // ============================================================================= // WITH MANY LINKS // ============================================================================= export const ManyLinks: Story = { name: "With Many Links", render: (args) => , args: { baseUrl: "https://short.link", links: [ ...sampleLinks, { id: "4", originalUrl: "https://example.com.ai/pricing", shortCode: "pricing", shortUrl: "https://short.link/pricing", title: "Pricing Page", clicks: 2500, createdAt: new Date("2024-01-20"), }, { id: "5", originalUrl: "https://example.com.ai/signup", shortCode: "signup", shortUrl: "https://short.link/signup", title: "Sign Up", clicks: 5000, createdAt: new Date("2024-01-25"), }, ], }, };