2025-03-25 21:47:40 +08:00
"use client"
import { useState } from "react"
import { Copy , CheckCheck , ExternalLink , ImageIcon , UserCircle , Code } from "lucide-react"
import { Button } from "@/components/ui/button"
import { Card , CardContent , CardDescription , CardFooter , CardHeader , CardTitle } from "@/components/ui/card"
import { Tabs , TabsContent , TabsList , TabsTrigger } from "@/components/ui/tabs"
import { Alert , AlertDescription , AlertTitle } from "@/components/ui/alert"
import { AlertTriangle } from "lucide-react"
import { Badge } from "@/components/ui/badge"
export default function Home() {
const [ copied , setCopied ] = useState < string | null > ( null )
const baseUrl = typeof window !== "undefined" ? window . location . origin : ""
const randomImageUrl = ` ${ baseUrl } /random-image `
2025-06-07 11:31:49 +08:00
const gravatarProxyUrl = ` ${ baseUrl } /avatar `
2025-03-25 21:47:40 +08:00
const copyToClipboard = ( text : string , id : string ) = > {
navigator . clipboard . writeText ( text )
setCopied ( id )
setTimeout ( ( ) = > setCopied ( null ) , 2000 )
}
return (
< div className = "min-h-screen bg-gradient-to-b from-slate-50 to-slate-100 dark:from-slate-950 dark:to-slate-900" >
< div className = "container mx-auto px-4 py-12" >
< header className = "text-center mb-16 pt-8" >
< h1 className = "text-4xl md:text-5xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-primary to-blue-600 mb-4" >
API Services
< / h1 >
2025-06-07 11:31:49 +08:00
< p className = "text-lg text-slate-600 dark:text-slate-400 max-w-2xl mx-auto" > Connect the world with us < / p >
2025-03-25 21:47:40 +08:00
< / header >
< Alert
variant = "destructive"
className = "mb-12 max-w-4xl mx-auto bg-red-50 border border-red-200 text-red-800 dark:bg-red-950 dark:border-red-800 dark:text-red-200"
>
< AlertTriangle className = "h-5 w-5 mr-2 text-red-600 dark:text-red-400" / >
< AlertTitle className = "font-medium" > Access Restricted < / AlertTitle >
< AlertDescription className = "text-sm md:text-base" >
The API is not open to the public . If you need it , please contact us at { " " }
< a
href = "mailto:10010@spircape.com"
className = "font-medium underline hover:text-red-600 dark:hover:text-red-300 transition-colors"
>
10010 @spircape . com
< / a >
< / AlertDescription >
< / Alert >
< Card className = "border-none shadow-lg mb-8" >
< CardHeader className = "bg-gradient-to-r from-primary/10 to-blue-500/10 border-b" >
< CardTitle className = "flex items-center gap-2" >
< Code className = "h-5 w-5" / >
Integration Guide
< / CardTitle >
< CardDescription > Follow these examples to integrate our services into your application < / CardDescription >
< / CardHeader >
< CardContent className = "pt-6" >
< Tabs defaultValue = "random-image" >
< TabsList className = "mb-6 grid w-full grid-cols-2" >
< TabsTrigger value = "random-image" className = "flex items-center gap-2" >
< ImageIcon className = "h-4 w-4" / >
Random Image
< / TabsTrigger >
< TabsTrigger value = "gravatar" className = "flex items-center gap-2" >
< UserCircle className = "h-4 w-4" / >
Gravatar Proxy
< / TabsTrigger >
< / TabsList >
< TabsContent value = "random-image" className = "space-y-8" >
< div className = "space-y-4" >
< div className = "flex items-center gap-2" >
< h3 className = "text-xl font-medium" > Random Image API < / h3 >
< Badge variant = "outline" className = "bg-primary/10 text-primary border-primary/20" >
GET
< / Badge >
< / div >
< p className = "text-slate-600 dark:text-slate-400" >
This API randomly serves an image from a predefined collection . Perfect for placeholder images ,
random backgrounds , or testing purposes .
< / p >
< div className = "space-y-6 mt-8" >
< div >
< h4 className = "font-medium flex items-center gap-2 mb-3" >
< Code className = "h-4 w-4 text-primary" / >
HTML Usage
< / h4 >
< div className = "relative" >
< pre className = "bg-slate-950 text-slate-100 p-4 rounded-md overflow-x-auto" >
< code > { ` <img src=" ${ randomImageUrl } " alt="Random image" /> ` } < / code >
< / pre >
< Button
variant = "ghost"
size = "sm"
className = "absolute top-2 right-2 text-slate-400 hover:text-white hover:bg-slate-800"
onClick = { ( ) = >
copyToClipboard ( ` <img src=" ${ randomImageUrl } " alt="Random image" /> ` , "html-random" )
}
>
{ copied === "html-random" ? < CheckCheck className = "h-4 w-4" / > : < Copy className = "h-4 w-4" / > }
< / Button >
< / div >
< / div >
< div >
< h4 className = "font-medium flex items-center gap-2 mb-3" >
< Code className = "h-4 w-4 text-primary" / >
React Usage
< / h4 >
< div className = "relative" >
< pre className = "bg-slate-950 text-slate-100 p-4 rounded-md overflow-x-auto" >
< code > { ` import { useState } from 'react'; \ n \ nfunction RandomImage() { \ n const [refresh, setRefresh] = useState(0); \ n \ n return ( \ n <img \ n src={ \` ${ randomImageUrl || "/placeholder.svg" } ?t= \ ${ refresh } \` } \ n alt="Random image" \ n onClick={() => setRefresh(Date.now())} \ n className="cursor-pointer transition-opacity hover:opacity-90" \ n /> \ n ); \ n} ` } < / code >
< / pre >
< Button
variant = "ghost"
size = "sm"
className = "absolute top-2 right-2 text-slate-400 hover:text-white hover:bg-slate-800"
onClick = { ( ) = >
copyToClipboard (
` import { useState } from 'react'; \ n \ nfunction RandomImage() { \ n const [refresh, setRefresh] = useState(0); \ n \ n return ( \ n <img \ n src={ \` ${ randomImageUrl || "/placeholder.svg" } ?t= \ ${ refresh } \` } \ n alt="Random image" \ n onClick={() => setRefresh(Date.now())} \ n className="cursor-pointer transition-opacity hover:opacity-90" \ n /> \ n ); \ n} ` ,
"react-random" ,
)
}
>
{ copied === "react-random" ? (
< CheckCheck className = "h-4 w-4" / >
) : (
< Copy className = "h-4 w-4" / >
) }
< / Button >
< / div >
< / div >
< / div >
< / div >
< / TabsContent >
< TabsContent value = "gravatar" className = "space-y-8" >
< div className = "space-y-4" >
< div className = "flex items-center gap-2" >
< h3 className = "text-xl font-medium" > Gravatar Proxy < / h3 >
< Badge variant = "outline" className = "bg-primary/10 text-primary border-primary/20" >
GET
< / Badge >
< / div >
< p className = "text-slate-600 dark:text-slate-400" >
Our Gravatar proxy service improves loading speed and reliability for Gravatar images . It caches and
optimizes avatar delivery for your applications .
< / p >
< div className = "space-y-6 mt-8" >
< div >
< h4 className = "font-medium flex items-center gap-2 mb-3" >
< Code className = "h-4 w-4 text-primary" / >
Basic Usage
< / h4 >
< div className = "relative" >
< pre className = "bg-slate-950 text-slate-100 p-4 rounded-md overflow-x-auto" >
2025-06-07 11:31:49 +08:00
< code > { ` <!-- Replace [EMAIL_HASH] with MD5 hash of the email --> \ n<img src=" ${ gravatarProxyUrl } /[EMAIL_HASH]" alt="User avatar" /> ` } < / code >
2025-03-25 21:47:40 +08:00
< / pre >
< Button
variant = "ghost"
size = "sm"
className = "absolute top-2 right-2 text-slate-400 hover:text-white hover:bg-slate-800"
onClick = { ( ) = >
copyToClipboard (
2025-06-07 11:31:49 +08:00
` <!-- Replace [EMAIL_HASH] with MD5 hash of the email --> \ n<img src=" ${ gravatarProxyUrl } /[EMAIL_HASH]" alt="User avatar" /> ` ,
2025-03-25 21:47:40 +08:00
"html-gravatar" ,
)
}
>
{ copied === "html-gravatar" ? (
< CheckCheck className = "h-4 w-4" / >
) : (
< Copy className = "h-4 w-4" / >
) }
< / Button >
< / div >
< / div >
< div >
< h4 className = "font-medium flex items-center gap-2 mb-3" >
< Code className = "h-4 w-4 text-primary" / >
With Size Parameter
< / h4 >
< div className = "relative" >
< pre className = "bg-slate-950 text-slate-100 p-4 rounded-md overflow-x-auto" >
2025-06-07 11:31:49 +08:00
< code > { ` <!-- Set size to 200px --> \ n<img src=" ${ gravatarProxyUrl } /[EMAIL_HASH]?s=200" alt="User avatar" /> ` } < / code >
2025-03-25 21:47:40 +08:00
< / pre >
< Button
variant = "ghost"
size = "sm"
className = "absolute top-2 right-2 text-slate-400 hover:text-white hover:bg-slate-800"
onClick = { ( ) = >
copyToClipboard (
2025-06-07 11:31:49 +08:00
` <!-- Set size to 200px --> \ n<img src=" ${ gravatarProxyUrl } /[EMAIL_HASH]?s=200" alt="User avatar" /> ` ,
2025-03-25 21:47:40 +08:00
"size-gravatar" ,
)
}
>
{ copied === "size-gravatar" ? (
< CheckCheck className = "h-4 w-4" / >
) : (
< Copy className = "h-4 w-4" / >
) }
< / Button >
< / div >
< / div >
< div >
< h4 className = "font-medium flex items-center gap-2 mb-3" >
< Code className = "h-4 w-4 text-primary" / >
With Default Image
< / h4 >
< div className = "relative" >
< pre className = "bg-slate-950 text-slate-100 p-4 rounded-md overflow-x-auto" >
2025-06-07 11:31:49 +08:00
< code > { ` <!-- Use 'identicon' as default if email has no Gravatar --> \ n<img src=" ${ gravatarProxyUrl } /[EMAIL_HASH]?d=identicon" alt="User avatar" /> ` } < / code >
2025-03-25 21:47:40 +08:00
< / pre >
< Button
variant = "ghost"
size = "sm"
className = "absolute top-2 right-2 text-slate-400 hover:text-white hover:bg-slate-800"
onClick = { ( ) = >
copyToClipboard (
2025-06-07 11:31:49 +08:00
` <!-- Use 'identicon' as default if email has no Gravatar --> \ n<img src=" ${ gravatarProxyUrl } /[EMAIL_HASH]?d=identicon" alt="User avatar" /> ` ,
2025-03-25 21:47:40 +08:00
"default-gravatar" ,
)
}
>
{ copied === "default-gravatar" ? (
< CheckCheck className = "h-4 w-4" / >
) : (
< Copy className = "h-4 w-4" / >
) }
< / Button >
< / div >
< / div >
< / div >
< / div >
< / TabsContent >
< / Tabs >
< / CardContent >
< CardFooter className = "border-t bg-slate-50 dark:bg-slate-900 py-4" >
< div className = "flex items-center gap-2 text-sm text-slate-600 dark:text-slate-400" >
< ExternalLink className = "h-4 w-4" / >
2025-06-07 11:31:49 +08:00
< span >
The above is for example only , please adjust according to the specific development environment
< / span >
2025-03-25 21:47:40 +08:00
< / div >
< / CardFooter >
< / Card >
< footer className = "text-center text-slate-500 text-sm py-4 border-t border-slate-200 dark:border-slate-800" >
< div className = "flex justify-center items-center" >
< p > © { new Date ( ) . getFullYear ( ) } Spircape . All rights reserved . < / p >
< / div >
< / footer >
< / div >
< / div >
)
}