Skip to content

Commit

Permalink
refactor: with store filter
Browse files Browse the repository at this point in the history
  • Loading branch information
rharkor committed Sep 18, 2024
1 parent 4ba9e0a commit eb73138
Show file tree
Hide file tree
Showing 11 changed files with 227 additions and 19 deletions.
8 changes: 7 additions & 1 deletion packages/cli-app/src/app/plugins/content.dr.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { ChooseStoreDr } from "@/components/choose-store.dr"
import { HeaderDr } from "@/components/ui/header.dr"
import { dictionaryRequirements } from "@/lib/utils/dictionary"

import { PluginDr } from "./plugin.dr"

export const PluginsContentDr = dictionaryRequirements({ plugins: true, search: true }, HeaderDr, PluginDr)
export const PluginsContentDr = dictionaryRequirements(
{ plugins: true, search: true, stores: true },
HeaderDr,
PluginDr,
ChooseStoreDr
)
57 changes: 53 additions & 4 deletions packages/cli-app/src/app/plugins/content.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
"use client"

import { useEffect, useState } from "react"
import { useEffect, useMemo, useState } from "react"
import { useSearchParams } from "next/navigation"

import { ChevronRight } from "lucide-react"

import ChooseStore from "@/components/choose-store"
import Header from "@/components/ui/header"
import { TDictionary } from "@/lib/langs"
import { trpc } from "@/lib/trpc/client"
import { RouterOutputs } from "@/lib/trpc/utils"
import { getItemUID } from "@next-boilerplate/cli-helpers/stores"
import { Input } from "@nextui-org/input"
import { Link } from "@nextui-org/link"

import { PluginsContentDr } from "./content.dr"
import Plugin from "./plugin"
Expand All @@ -16,16 +21,27 @@ type TPlugins = RouterOutputs["plugins"]["getPlugins"]

export default function PluginsContent({
ssrPlugins,
ssrStores,
initialStoreName,
initialStoreVersion,
ssrConfiguration,
dictionary,
}: {
ssrPlugins: TPlugins
ssrPlugins: TPlugins | undefined
ssrStores: RouterOutputs["stores"]["getStores"]
ssrConfiguration: RouterOutputs["configuration"]["getConfiguration"]
initialStoreName: string | null
initialStoreVersion: string | null
dictionary: TDictionary<typeof PluginsContentDr>
}) {
const [_search, _setSearch] = useState("")
const [search, setSearch] = useState(_search)

const sp = useSearchParams()

const storeName = useMemo(() => sp.get("storeName"), [sp])
const storeVersion = useMemo(() => sp.get("storeVersion"), [sp])

// Debounce search
useEffect(() => {
const timeout = setTimeout(() => {
Expand All @@ -34,21 +50,54 @@ export default function PluginsContent({
return () => clearTimeout(timeout)
}, [search])

const isInitialFilter = search === ""
const isInitialFilter = search === "" && storeName === initialStoreName && storeVersion === initialStoreVersion

const plugins = trpc.plugins.getPlugins.useQuery(
{
search: _search,
store: {
name: storeName ?? "",
version: storeVersion ?? "",
},
},
{
initialData: isInitialFilter ? ssrPlugins : undefined,
enabled: storeName && storeVersion ? true : false,
}
)

const stores = trpc.stores.getStores.useQuery(undefined, {
initialData: ssrStores,
})

if (!storeName || !storeVersion) {
return (
<ChooseStore
dictionary={dictionary}
stores={stores.data}
isLoading={stores.isLoading}
search={search}
setSearch={setSearch}
lnk="/plugins"
/>
)
}

return (
<>
<Header
title={dictionary.plugins}
title={
<>
{dictionary.plugins}
<span className="flex items-center gap-0.5 text-xs text-muted-foreground">
<Link href={"/plugins"} className="text-xs">
{dictionary.stores}
</Link>
<ChevronRight className="size-4" />
{storeName}
</span>
</>
}
dictionary={dictionary}
actions={<Input value={search} onValueChange={setSearch} placeholder={dictionary.search} />}
/>
Expand Down
28 changes: 26 additions & 2 deletions packages/cli-app/src/app/plugins/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { headers } from "next/headers"

import Section from "@/components/ui/section"
import { getDictionary } from "@/lib/langs"
import { trpc } from "@/lib/trpc/server"
Expand All @@ -10,12 +12,34 @@ import { PluginsContentDr } from "./content.dr"
export default async function Plugins() {
const locale = extractLocale()
const dictionary = await getDictionary(locale, dictionaryRequirements(PluginsContentDr))
const ssrPlugins = await trpc.plugins.getPlugins({})

const headersStore = headers()
const url = new URL(headersStore.get("x-url") as string)
const storeName = url.searchParams.get("storeName")
const storeVersion = url.searchParams.get("storeVersion")

const ssrPlugins =
storeName && storeVersion
? await trpc.plugins.getPlugins({
store: {
name: storeName,
version: storeVersion,
},
})
: undefined
const ssrStores = await trpc.stores.getStores()
const ssrConfiguration = await trpc.configuration.getConfiguration()

return (
<Section>
<PluginsContent ssrPlugins={ssrPlugins} dictionary={dictionary} ssrConfiguration={ssrConfiguration} />
<PluginsContent
initialStoreName={storeName}
initialStoreVersion={storeVersion}
ssrStores={ssrStores}
ssrPlugins={ssrPlugins}
dictionary={dictionary}
ssrConfiguration={ssrConfiguration}
/>
</Section>
)
}
5 changes: 4 additions & 1 deletion packages/cli-app/src/app/templates/content.dr.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { ChooseStoreDr } from "@/components/choose-store.dr"
import { HeaderDr } from "@/components/ui/header.dr"
import { dictionaryRequirements } from "@/lib/utils/dictionary"

export const TemplatesContentDr = dictionaryRequirements(
{
templates: true,
search: true,
stores: true,
},
HeaderDr
HeaderDr,
ChooseStoreDr
)
57 changes: 52 additions & 5 deletions packages/cli-app/src/app/templates/content.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,43 @@
"use client"

import { useEffect, useState } from "react"
import { useEffect, useMemo, useState } from "react"
import { useSearchParams } from "next/navigation"

import { BookDashed } from "lucide-react"
import { BookDashed, ChevronRight } from "lucide-react"

import ChooseStore from "@/components/choose-store"
import Header from "@/components/ui/header"
import ItemCard from "@/components/ui/item-card"
import { TDictionary } from "@/lib/langs"
import { trpc } from "@/lib/trpc/client"
import { RouterOutputs } from "@/lib/trpc/utils"
import { getItemUID } from "@next-boilerplate/cli-helpers/stores"
import { Input } from "@nextui-org/input"
import { Link } from "@nextui-org/link"

import { TemplatesContentDr } from "./content.dr"

export default function TemplatesContent({
initialStoreName,
initialStoreVersion,
ssrStores,
ssrTemplates,
dictionary,
}: {
ssrTemplates: RouterOutputs["templates"]["getTemplates"]
initialStoreName: string | null
initialStoreVersion: string | null
ssrStores: RouterOutputs["stores"]["getStores"]
ssrTemplates: RouterOutputs["templates"]["getTemplates"] | undefined
dictionary: TDictionary<typeof TemplatesContentDr>
}) {
const [_search, _setSearch] = useState("")
const [search, setSearch] = useState(_search)

const sp = useSearchParams()

const storeName = useMemo(() => sp.get("storeName"), [sp])
const storeVersion = useMemo(() => sp.get("storeVersion"), [sp])

// Debounce search
useEffect(() => {
const timeout = setTimeout(() => {
Expand All @@ -32,21 +46,54 @@ export default function TemplatesContent({
return () => clearTimeout(timeout)
}, [search])

const isInitialFilter = search === ""
const isInitialFilter = search === "" && storeName === initialStoreName && storeVersion === initialStoreVersion

const templates = trpc.templates.getTemplates.useQuery(
{
search: _search,
store: {
name: storeName ?? "",
version: storeVersion ?? "",
},
},
{
initialData: isInitialFilter ? ssrTemplates : undefined,
enabled: storeName && storeVersion ? true : false,
}
)

const stores = trpc.stores.getStores.useQuery(undefined, {
initialData: ssrStores,
})

if (!storeName || !storeVersion) {
return (
<ChooseStore
dictionary={dictionary}
stores={stores.data}
isLoading={stores.isLoading}
search={search}
setSearch={setSearch}
lnk="/templates"
/>
)
}

return (
<>
<Header
title={dictionary.templates}
title={
<>
{dictionary.templates}
<span className="flex items-center gap-0.5 text-xs text-muted-foreground">
<Link href={"/templates"} className="text-xs">
{dictionary.stores}
</Link>
<ChevronRight className="size-4" />
{storeName}
</span>
</>
}
dictionary={dictionary}
actions={<Input value={search} onValueChange={setSearch} placeholder={dictionary.search} />}
/>
Expand Down
27 changes: 25 additions & 2 deletions packages/cli-app/src/app/templates/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { headers } from "next/headers"

import Section from "@/components/ui/section"
import { getDictionary } from "@/lib/langs"
import { trpc } from "@/lib/trpc/server"
Expand All @@ -10,11 +12,32 @@ import { TemplatesContentDr } from "./content.dr"
export default async function Templates() {
const locale = extractLocale()
const dictionary = await getDictionary(locale, dictionaryRequirements(TemplatesContentDr))
const ssrTemplates = await trpc.templates.getTemplates({})

const headersStore = headers()
const url = new URL(headersStore.get("x-url") as string)
const storeName = url.searchParams.get("storeName")
const storeVersion = url.searchParams.get("storeVersion")

const ssrTemplates =
storeName && storeVersion
? await trpc.templates.getTemplates({
store: {
name: storeName,
version: storeVersion,
},
})
: undefined
const ssrStores = await trpc.stores.getStores()

return (
<Section>
<TemplatesContent ssrTemplates={ssrTemplates} dictionary={dictionary} />
<TemplatesContent
initialStoreName={storeName}
initialStoreVersion={storeVersion}
ssrStores={ssrStores}
ssrTemplates={ssrTemplates}
dictionary={dictionary}
/>
</Section>
)
}
5 changes: 5 additions & 0 deletions packages/cli-app/src/components/choose-store.dr.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { dictionaryRequirements } from "@/lib/utils/dictionary"

import { HeaderDr } from "./ui/header.dr"

export const ChooseStoreDr = dictionaryRequirements({ selectStore: true, storeVersion: true, search: true }, HeaderDr)
49 changes: 49 additions & 0 deletions packages/cli-app/src/components/choose-store.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Store } from "lucide-react"

import { TDictionary } from "@/lib/langs"
import { RouterOutputs } from "@/lib/trpc/utils"
import { Input } from "@nextui-org/input"

import Header from "./ui/header"
import ItemCard from "./ui/item-card"
import { ChooseStoreDr } from "./choose-store.dr"

export default function ChooseStore({
dictionary,
stores,
isLoading,
search,
setSearch,
lnk,
}: {
dictionary: TDictionary<typeof ChooseStoreDr>
stores: RouterOutputs["stores"]["getStores"] | undefined
isLoading: boolean
search: string
setSearch: (search: string) => void
lnk: string
}) {
return (
<>
<Header
title={dictionary.selectStore}
dictionary={dictionary}
actions={<Input value={search} onValueChange={setSearch} placeholder={dictionary.search} />}
/>
<ul className="flex flex-1 flex-col gap-2">
{isLoading
? [...Array(5)].map((_, i) => <ItemCard key={i} isLoading id="" title="" description="" />)
: stores?.stores.map((store) => (
<ItemCard
key={store.uid}
id={store.uid}
title={store.name}
description={dictionary.storeVersion + ": " + store.version}
href={`${lnk}?storeName=${store.name}&storeVersion=${store.version}`}
endContent={<Store className="absolute right-2 top-2 size-4 text-primary" />}
/>
))}
</ul>
</>
)
}
4 changes: 2 additions & 2 deletions packages/cli-app/src/components/ui/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default function Header({
withBack,
dictionary,
}: {
title: string
title: string | React.ReactNode
actions?: React.ReactNode
withBack?: boolean
dictionary: TDictionary<typeof HeaderDr>
Expand All @@ -26,7 +26,7 @@ export default function Header({

const content = (
<div className="flex items-center justify-between gap-3">
<h1 className="text-3xl">{title}</h1>
<h1 className="flex flex-col gap-1 text-3xl">{title}</h1>
<div className="flex flex-row gap-2">{actions}</div>
</div>
)
Expand Down
Loading

0 comments on commit eb73138

Please sign in to comment.