Migrate the Nuxt 3 + Vue 3 SSR frontend application for basicstack.org to our self-hosted Forgejo instance. This repository will serve as the source for all future development and deployment of the basicstack.org website. The application includes: - Nuxt 3 + Vue 3 SSR setup - Directus CMS integration - Tailwind CSS styling - Kubernetes deployment manifests - Docker containerization Co-Authored-By: Paperclip <noreply@paperclip.ing>
197 lines
4.3 KiB
TypeScript
197 lines
4.3 KiB
TypeScript
import { createDirectus, rest, readItems, readItem, readSingleton } from '@directus/sdk'
|
|
|
|
type SoftwarePackage = {
|
|
id: number
|
|
status: 'published' | 'draft' | 'archived'
|
|
name: string
|
|
slug: string
|
|
short_description: string
|
|
full_description: string | null
|
|
logo: string | null
|
|
website_url: string | null
|
|
documentation_url: string | null
|
|
screenshots: PackageScreenshot[]
|
|
deployment_details: PackageDeploymentDetail[]
|
|
troubleshooting: PackageTroubleshooting[]
|
|
}
|
|
|
|
type PackageScreenshot = {
|
|
id: number
|
|
image: string
|
|
title: string | null
|
|
caption: string | null
|
|
sort: number | null
|
|
}
|
|
|
|
type PackageDeploymentDetail = {
|
|
id: number
|
|
title: string
|
|
content: string | null
|
|
sort: number | null
|
|
}
|
|
|
|
type PackageTroubleshooting = {
|
|
id: number
|
|
title: string
|
|
problem: string | null
|
|
solution: string | null
|
|
sort: number | null
|
|
}
|
|
|
|
type InfrastructureContent = {
|
|
id: number
|
|
status: 'published' | 'draft'
|
|
category: 'hosting' | 'security' | 'monitoring' | 'backup' | 'disaster_recovery'
|
|
title: string
|
|
slug: string | null
|
|
summary: string | null
|
|
content: string | null
|
|
}
|
|
|
|
type Page = {
|
|
id: number
|
|
status: 'published' | 'draft'
|
|
title: string
|
|
slug: string
|
|
content: string | null
|
|
meta_title: string | null
|
|
meta_description: string | null
|
|
}
|
|
|
|
type NavigationItem = {
|
|
id: number
|
|
status: 'published' | 'draft'
|
|
label: string
|
|
type: 'page' | 'external' | 'custom'
|
|
page_id: number | null
|
|
external_url: string | null
|
|
custom_route: string | null
|
|
parent_id: number | null
|
|
sort: number | null
|
|
}
|
|
|
|
type SiteSettings = {
|
|
id: number
|
|
logo: string | null
|
|
}
|
|
|
|
type Schema = {
|
|
software_packages: SoftwarePackage[]
|
|
package_screenshots: PackageScreenshot[]
|
|
package_deployment_details: PackageDeploymentDetail[]
|
|
package_troubleshooting: PackageTroubleshooting[]
|
|
infrastructure_content: InfrastructureContent[]
|
|
pages: Page[]
|
|
navigation: NavigationItem[]
|
|
site_settings: SiteSettings
|
|
}
|
|
|
|
export function useDirectus() {
|
|
const config = useRuntimeConfig()
|
|
|
|
const client = createDirectus<Schema>(config.public.directusUrl).with(rest())
|
|
|
|
async function getPackages() {
|
|
return client.request(
|
|
readItems('software_packages', {
|
|
filter: { status: { _eq: 'published' } },
|
|
fields: ['*', 'screenshots.*', 'deployment_details.*', 'troubleshooting.*'],
|
|
sort: ['sort', 'name'],
|
|
})
|
|
)
|
|
}
|
|
|
|
async function getPackage(slug: string) {
|
|
const items = await client.request(
|
|
readItems('software_packages', {
|
|
filter: {
|
|
_and: [
|
|
{ status: { _eq: 'published' } },
|
|
{ slug: { _eq: slug } },
|
|
]
|
|
},
|
|
fields: ['*', 'screenshots.*', 'deployment_details.*', 'troubleshooting.*'],
|
|
limit: 1,
|
|
})
|
|
)
|
|
return items[0] ?? null
|
|
}
|
|
|
|
async function getInfrastructure() {
|
|
return client.request(
|
|
readItems('infrastructure_content', {
|
|
filter: { status: { _eq: 'published' } },
|
|
sort: ['category', 'title'],
|
|
})
|
|
)
|
|
}
|
|
|
|
async function getInfrastructureItem(slug: string) {
|
|
const items = await client.request(
|
|
readItems('infrastructure_content', {
|
|
filter: {
|
|
_and: [
|
|
{ status: { _eq: 'published' } },
|
|
{ slug: { _eq: slug } },
|
|
]
|
|
},
|
|
limit: 1,
|
|
})
|
|
)
|
|
return items[0] ?? null
|
|
}
|
|
|
|
async function getPages() {
|
|
return client.request(
|
|
readItems('pages', {
|
|
filter: { status: { _eq: 'published' } },
|
|
sort: ['sort', 'title'],
|
|
})
|
|
)
|
|
}
|
|
|
|
async function getPage(slug: string) {
|
|
const items = await client.request(
|
|
readItems('pages', {
|
|
filter: {
|
|
_and: [
|
|
{ status: { _eq: 'published' } },
|
|
{ slug: { _eq: slug } },
|
|
]
|
|
},
|
|
limit: 1,
|
|
})
|
|
)
|
|
return items[0] ?? null
|
|
}
|
|
|
|
async function getNavigation() {
|
|
return client.request(
|
|
readItems('navigation', {
|
|
filter: { status: { _eq: 'published' } },
|
|
sort: ['sort'],
|
|
})
|
|
)
|
|
}
|
|
|
|
async function getSiteSettings() {
|
|
return client.request(readSingleton('site_settings'))
|
|
}
|
|
|
|
function getAssetUrl(fileId: string) {
|
|
return `${config.public.directusUrl}/assets/${fileId}`
|
|
}
|
|
|
|
return {
|
|
client,
|
|
getPackages,
|
|
getPackage,
|
|
getInfrastructure,
|
|
getInfrastructureItem,
|
|
getPages,
|
|
getPage,
|
|
getNavigation,
|
|
getSiteSettings,
|
|
getAssetUrl,
|
|
}
|
|
}
|