diff --git a/landing/.gitignore b/landing/.gitignore new file mode 100644 index 0000000..06f339f --- /dev/null +++ b/landing/.gitignore @@ -0,0 +1,39 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js +.yarn/install-state.gz + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts + +# devup-ui +/df diff --git a/landing/README.md b/landing/README.md new file mode 100644 index 0000000..95f69cf --- /dev/null +++ b/landing/README.md @@ -0,0 +1,85 @@ +# Devup API Landing Page + +This is the landing page for Devup API, built with **Next.js** and **Devup UI**. + +## Tech Stack + +- **Next.js 15+** - React framework with App Router +- **Devup UI** - Zero-runtime CSS-in-JS styling library +- **TypeScript** - Type safety +- **React 19** - Latest React features + +## Getting Started + +### Install Dependencies + +```bash +npm install +# or +pnpm install +# or +yarn install +``` + +### Run Development Server + +```bash +npm run dev +``` + +Open [http://localhost:3000](http://localhost:3000) to see the landing page. + +### Build for Production + +```bash +npm run build +``` + +This will generate a static export in the `out/` directory. + +### Preview Production Build + +```bash +npm run start +``` + +## Project Structure + +``` +landing/ +├── public/ # Static assets +├── src/ +│ ├── app/ # Next.js App Router +│ │ ├── layout.tsx +│ │ ├── page.tsx +│ │ ├── Hero.tsx +│ │ ├── Features.tsx +│ │ ├── CodeExamples.tsx +│ │ ├── Packages.tsx +│ │ └── Footer.tsx +│ └── components/ # Reusable components +├── devup.json # Devup UI theme configuration +├── next.config.ts # Next.js configuration +├── tsconfig.json # TypeScript configuration +└── package.json +``` + +## Customization + +### Theme + +Edit `devup.json` to customize colors, typography, spacing, and breakpoints. + +### Content + +- **Hero Section**: `src/app/Hero.tsx` +- **Features**: `src/app/Features.tsx` +- **Code Examples**: `src/app/CodeExamples.tsx` +- **Packages**: `src/app/Packages.tsx` +- **Footer**: `src/app/Footer.tsx` + +## Learn More + +- [Next.js Documentation](https://nextjs.org/docs) +- [Devup UI Documentation](https://github.com/dev-five-git/devup-ui) +- [Devup API Documentation](https://github.com/dev-five-git/devup-api) diff --git a/landing/devup.json b/landing/devup.json new file mode 100644 index 0000000..2dd90b4 --- /dev/null +++ b/landing/devup.json @@ -0,0 +1,98 @@ +{ + "theme": { + "colors": { + "light": { + "primary": "#2563eb", + "primaryHover": "#1d4ed8", + "secondary": "#3b82f6", + "accent": "#8b5cf6", + "text": "#1f2937", + "textLight": "#6b7280", + "textMuted": "#9ca3af", + "bg": "#ffffff", + "bgSecondary": "#f9fafb", + "bgTertiary": "#f3f4f6", + "border": "#e5e7eb", + "success": "#10b981", + "warning": "#f59e0b", + "error": "#ef4444", + "codeBg": "#1f2937", + "codeText": "#e5e7eb" + }, + "dark": { + "primary": "#60a5fa", + "primaryHover": "#3b82f6", + "secondary": "#1e40af", + "accent": "#a78bfa", + "text": "#f3f4f6", + "textLight": "#d1d5db", + "textMuted": "#9ca3af", + "bg": "#111827", + "bgSecondary": "#1f2937", + "bgTertiary": "#374151", + "border": "#374151", + "success": "#34d399", + "warning": "#fbbf24", + "error": "#f87171", + "codeBg": "#0f172a", + "codeText": "#e2e8f0" + } + }, + "textStyles": { + "h1": { + "fontSize": ["2rem", "2.5rem", "3.5rem"], + "fontWeight": 800, + "lineHeight": 1.2, + "letterSpacing": "-0.02em" + }, + "h2": { + "fontSize": ["1.75rem", "2rem", "2.5rem"], + "fontWeight": 700, + "lineHeight": 1.3, + "letterSpacing": "-0.02em" + }, + "h3": { + "fontSize": ["1.25rem", "1.5rem", "1.75rem"], + "fontWeight": 600, + "lineHeight": 1.4, + "letterSpacing": "-0.01em" + }, + "body": { + "fontSize": ["0.875rem", "1rem", "1.125rem"], + "fontWeight": 400, + "lineHeight": 1.6 + }, + "bodyLarge": { + "fontSize": ["1rem", "1.125rem", "1.25rem"], + "fontWeight": 400, + "lineHeight": 1.6 + }, + "button": { + "fontSize": "1rem", + "fontWeight": 600, + "lineHeight": 1 + }, + "code": { + "fontFamily": "Monaco, 'Courier New', monospace", + "fontSize": "0.875rem", + "lineHeight": 1.6 + } + }, + "spacing": { + "xs": "0.25rem", + "sm": "0.5rem", + "md": "1rem", + "lg": "1.5rem", + "xl": "2rem", + "2xl": "3rem", + "3xl": "4rem", + "4xl": "6rem" + }, + "breakpoints": { + "sm": "640px", + "md": "768px", + "lg": "1024px", + "xl": "1280px" + } + } +} diff --git a/landing/next.config.ts b/landing/next.config.ts new file mode 100644 index 0000000..230f1c5 --- /dev/null +++ b/landing/next.config.ts @@ -0,0 +1,10 @@ +import type { NextConfig } from 'next' +import DevupUI from '@devup-ui/next-plugin' + +const nextConfig: NextConfig = { + pageExtensions: ['js', 'jsx', 'ts', 'tsx'], + output: 'export', + reactCompiler: true, +} + +export default DevupUI(nextConfig) diff --git a/landing/package.json b/landing/package.json new file mode 100644 index 0000000..7cfcbb7 --- /dev/null +++ b/landing/package.json @@ -0,0 +1,29 @@ +{ + "name": "devup-api-landing", + "version": "0.1.0", + "private": true, + "type": "module", + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "@devup-ui/react": "latest", + "@devup-ui/reset": "latest", + "clsx": "^2.1.1", + "next": "^15.1.3", + "react": "^19.0.0", + "react-dom": "^19.0.0" + }, + "devDependencies": { + "@devup-ui/next-plugin": "latest", + "@types/node": "^22", + "@types/react": "^19", + "@types/react-dom": "^19", + "eslint": "^9", + "eslint-config-next": "^15.1.3", + "typescript": "^5" + } +} diff --git a/landing/src/app/CodeExamples.tsx b/landing/src/app/CodeExamples.tsx new file mode 100644 index 0000000..0386b2f --- /dev/null +++ b/landing/src/app/CodeExamples.tsx @@ -0,0 +1,120 @@ +'use client' + +import { Box, Container, Grid } from '@devup-ui/react' + +const examples = [ + { + title: 'Installation & Setup', + code: `// Install for your build tool +npm install @devup-api/fetch @devup-api/vite-plugin + +// vite.config.ts +import { defineConfig } from 'vite' +import devupApi from '@devup-api/vite-plugin' + +export default defineConfig({ + plugins: [devupApi()], +})`, + }, + { + title: 'Basic Usage', + code: `import { createApi } from '@devup-api/fetch' + +const api = createApi('https://api.example.com') + +// Use operationId +const users = await api.get('getUsers', {}) + +// Or use the path directly +const user = await api.get('/users/{id}', { + params: { id: '123' }, +})`, + }, + { + title: 'React Query Integration', + code: `import { createQueryClient } from '@devup-api/react-query' + +const queryClient = createQueryClient(api) + +function UserProfile({ userId }) { + const { data, isLoading } = queryClient.useQuery( + 'get', + '/users/{id}', + { params: { id: userId } } + ) + return
{data?.name}
+}`, + }, + { + title: 'Type References', + code: `import { type DevupObject } from '@devup-api/fetch' + +// Access response types +type User = DevupObject['User'] +type Product = DevupObject['Product'] + +// Request types +type CreateUserRequest = + DevupObject<'request'>['CreateUserBody']`, + }, +] + +export default function CodeExamples() { + return ( + + + + 💻 Quick Examples + + + + {examples.map((example, index) => ( + + + {example.title} + + + {example.code} + + + ))} + + + + ) +} diff --git a/landing/src/app/Features.tsx b/landing/src/app/Features.tsx new file mode 100644 index 0000000..3a8e0eb --- /dev/null +++ b/landing/src/app/Features.tsx @@ -0,0 +1,95 @@ +'use client' + +import { Box, Container, Grid } from '@devup-ui/react' + +const features = [ + { + icon: '🔍', + title: 'OpenAPI-driven Types', + description: 'Reads openapi.json and transforms every path, method, schema into typed API functions. Parameters, request bodies, headers, responses — all typed automatically.', + }, + { + icon: '🪝', + title: 'Fetch-compatible Design', + description: 'Feels like using fetch, but with superpowers. Path params automatically replaced, query/body/header types enforced, typed success & error responses.', + }, + { + icon: '⚡', + title: 'Build Tool Integration', + description: 'Works seamlessly with Vite, Next.js, Webpack, and Rsbuild. Automatic type generation during build time with zero runtime overhead.', + }, + { + icon: '🔄', + title: 'React Query Support', + description: 'First-class integration with TanStack React Query. Use useQuery, useMutation, useInfiniteQuery with full type safety.', + }, + { + icon: '🌐', + title: 'Multiple API Servers', + description: 'Support for multiple OpenAPI schemas. Work with different API servers simultaneously with isolated type generation.', + }, + { + icon: '🛡️', + title: 'Type Safety', + description: 'Cold typing for initial development, bold typing for production. Gradual type enforcement ensures smooth developer experience.', + }, +] + +export default function Features() { + return ( + + + + ✨ Features + + + + {features.map((feature, index) => ( + + + {feature.icon} + + + {feature.title} + + + {feature.description} + + + ))} + + + + ) +} diff --git a/landing/src/app/Footer.tsx b/landing/src/app/Footer.tsx new file mode 100644 index 0000000..2ed0f69 --- /dev/null +++ b/landing/src/app/Footer.tsx @@ -0,0 +1,202 @@ +'use client' + +import Link from 'next/link' +import { Box, Container, Grid, Flex } from '@devup-ui/react' + +export default function Footer() { + return ( + + + + + + Devup API + + + A fully typed API client generator powered by OpenAPI. + Fetch-compatible, auto-generated types, zero generics required. + + + + + + Resources + + + + Documentation + + + Quick Start + + + Examples + + + Packages + + + + + + + Community + + + + GitHub + + + Issues + + + Pull Requests + + + npm + + + + + + + Company + + + 데브파이브 (DevFive) + + 사업자등록번호: 797-86-00705
+ 경기도 고양시 일산서구 대산로 89, 511-3
+ © 2021-2024 DevFive. All rights reserved. +
+
+
+
+ + + + Licensed under Apache 2.0 | Inspired by{' '} + + openapi-fetch + + + +
+
+ ) +} diff --git a/landing/src/app/Hero.tsx b/landing/src/app/Hero.tsx new file mode 100644 index 0000000..f93af90 --- /dev/null +++ b/landing/src/app/Hero.tsx @@ -0,0 +1,126 @@ +'use client' + +import Link from 'next/link' +import { Box, Container, Flex } from '@devup-ui/react' + +export default function Hero() { + return ( + + + + Devup API + + + + + 🔍 OpenAPI-driven + + + 🪝 Fetch-compatible + + + ⚡ Zero Runtime + + + + + A fully typed API client generator powered by OpenAPI.
+ Auto-generated types, zero generics required, just write API calls — the types are already there. +
+ + + + Get Started + + + View on GitHub + + +
+
+ ) +} diff --git a/landing/src/app/Packages.tsx b/landing/src/app/Packages.tsx new file mode 100644 index 0000000..efc01ce --- /dev/null +++ b/landing/src/app/Packages.tsx @@ -0,0 +1,73 @@ +'use client' + +import { Box, Container, Grid } from '@devup-ui/react' + +const packages = [ + { name: '@devup-api/core', description: 'Core types and interfaces' }, + { name: '@devup-api/utils', description: 'Utility functions for OpenAPI processing' }, + { name: '@devup-api/generator', description: 'TypeScript interface generator from OpenAPI schemas' }, + { name: '@devup-api/fetch', description: 'Type-safe API client' }, + { name: '@devup-api/react-query', description: 'TanStack React Query integration' }, + { name: '@devup-api/vite-plugin', description: 'Vite plugin for automatic type generation' }, + { name: '@devup-api/next-plugin', description: 'Next.js plugin for automatic type generation' }, + { name: '@devup-api/webpack-plugin', description: 'Webpack plugin for automatic type generation' }, + { name: '@devup-api/rsbuild-plugin', description: 'Rsbuild plugin for automatic type generation' }, +] + +export default function Packages() { + return ( + + + + 📦 Packages + + + + {packages.map((pkg, index) => ( + + + {pkg.name} + + + {pkg.description} + + + ))} + + + + ) +} diff --git a/landing/src/app/layout.tsx b/landing/src/app/layout.tsx new file mode 100644 index 0000000..a12c24f --- /dev/null +++ b/landing/src/app/layout.tsx @@ -0,0 +1,36 @@ +import type { Metadata } from 'next' +import '@devup-ui/reset' + +export const metadata: Metadata = { + title: 'Devup API - OpenAPI-driven Type-safe API Client', + description: 'A fully typed API client generator powered by OpenAPI. Fetch-compatible, auto-generated types, zero generics required.', + keywords: ['API', 'OpenAPI', 'TypeScript', 'Type-safe', 'Fetch', 'React', 'Next.js'], + authors: [{ name: 'DevFive' }], + openGraph: { + title: 'Devup API - OpenAPI-driven Type-safe API Client', + description: 'A fully typed API client generator powered by OpenAPI.', + type: 'website', + }, +} + +export default function RootLayout({ + children, +}: { + children: React.ReactNode +}) { + return ( + + + + + + {children} + + + ) +} diff --git a/landing/src/app/page.tsx b/landing/src/app/page.tsx new file mode 100644 index 0000000..997faae --- /dev/null +++ b/landing/src/app/page.tsx @@ -0,0 +1,17 @@ +import Hero from './Hero' +import Features from './Features' +import CodeExamples from './CodeExamples' +import Packages from './Packages' +import Footer from './Footer' + +export default function HomePage() { + return ( + <> + + + + +