@@ -8,14 +8,15 @@ import {
88} from "@/components/ui/command" ;
99import { basePath } from "@/config/siteConfig" ;
1010import { fetchCategories } from "@/lib/data" ;
11- import { Category } from "@/lib/types" ;
11+ import { Category , Script } from "@/lib/types" ;
1212import { cn } from "@/lib/utils" ;
1313import Image from "next/image" ;
1414import { useRouter } from "next/navigation" ;
1515import React from "react" ;
1616import { Badge } from "./ui/badge" ;
1717import { Button } from "./ui/button" ;
1818import { DialogTitle } from "./ui/dialog" ;
19+ import { Sparkles } from "lucide-react" ; // <- Hinzugefügt
1920
2021export const formattedBadge = ( type : string ) => {
2122 switch ( type ) {
@@ -31,11 +32,19 @@ export const formattedBadge = (type: string) => {
3132 return null ;
3233} ;
3334
35+ // random Script
36+ function getRandomScript ( categories : Category [ ] ) : Script | null {
37+ const allScripts = categories . flatMap ( ( cat ) => cat . scripts || [ ] ) ;
38+ if ( allScripts . length === 0 ) return null ;
39+ const idx = Math . floor ( Math . random ( ) * allScripts . length ) ;
40+ return allScripts [ idx ] ;
41+ }
42+
3443export default function CommandMenu ( ) {
3544 const [ open , setOpen ] = React . useState ( false ) ;
3645 const [ links , setLinks ] = React . useState < Category [ ] > ( [ ] ) ;
37- const router = useRouter ( ) ;
3846 const [ isLoading , setIsLoading ] = React . useState ( false ) ;
47+ const router = useRouter ( ) ;
3948
4049 React . useEffect ( ( ) => {
4150 const down = ( e : KeyboardEvent ) => {
@@ -45,7 +54,6 @@ export default function CommandMenu() {
4554 setOpen ( ( open ) => ! open ) ;
4655 }
4756 } ;
48-
4957 document . addEventListener ( "keydown" , down ) ;
5058 return ( ) => document . removeEventListener ( "keydown" , down ) ;
5159 } , [ ] ) ;
@@ -63,23 +71,58 @@ export default function CommandMenu() {
6371 } ) ;
6472 } ;
6573
74+ const openRandomScript = async ( ) => {
75+ if ( links . length === 0 ) {
76+ setIsLoading ( true ) ;
77+ try {
78+ const categories = await fetchCategories ( ) ;
79+ setLinks ( categories ) ;
80+ const randomScript = getRandomScript ( categories ) ;
81+ if ( randomScript ) {
82+ router . push ( `/scripts?id=${ randomScript . slug } ` ) ;
83+ }
84+ } finally {
85+ setIsLoading ( false ) ;
86+ }
87+ } else {
88+ const randomScript = getRandomScript ( links ) ;
89+ if ( randomScript ) {
90+ router . push ( `/scripts?id=${ randomScript . slug } ` ) ;
91+ }
92+ }
93+ } ;
94+
6695 return (
6796 < >
68- < Button
69- variant = "outline"
70- className = { cn (
71- "relative h-9 w-full justify-start rounded-[0.5rem] bg-muted/50 text-sm font-normal text-muted-foreground shadow-none sm:pr-12 md:w-40 lg:w-64" ,
72- ) }
73- onClick = { ( ) => {
74- fetchSortedCategories ( ) ;
75- setOpen ( true ) ;
76- } }
77- >
78- < span className = "inline-flex" > Search scripts...</ span >
79- < kbd className = "pointer-events-none absolute right-[0.3rem] top-[0.45rem] hidden h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium opacity-100 sm:flex" >
80- < span className = "text-xs" > ⌘</ span > K
81- </ kbd >
82- </ Button >
97+ < div className = "flex gap-2" >
98+ < Button
99+ variant = "outline"
100+ className = { cn (
101+ "relative h-9 w-full justify-start rounded-[0.5rem] bg-muted/50 text-sm font-normal text-muted-foreground shadow-none sm:pr-12 md:w-40 lg:w-64" ,
102+ ) }
103+ onClick = { ( ) => {
104+ fetchSortedCategories ( ) ;
105+ setOpen ( true ) ;
106+ } }
107+ >
108+ < span className = "inline-flex" > Search scripts...</ span >
109+ < kbd className = "pointer-events-none absolute right-[0.3rem] top-[0.45rem] hidden h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium opacity-100 sm:flex" >
110+ < span className = "text-xs" > ⌘</ span > K
111+ </ kbd >
112+ </ Button >
113+
114+ < Button
115+ variant = "outline"
116+ size = "icon"
117+ onClick = { openRandomScript }
118+ title = "Open random script"
119+ disabled = { isLoading }
120+ className = "h-9 w-9"
121+ >
122+ < Sparkles className = "h-5 w-5" />
123+ </ Button >
124+ </ div >
125+
83126 < CommandDialog open = { open } onOpenChange = { setOpen } >
84127 < DialogTitle className = "sr-only" > Search scripts</ DialogTitle >
85128 < CommandInput placeholder = "Search for a script..." />
0 commit comments