import { useEffect, useState } from 'react' import { fetchDrupalResource } from './lib/drupalClient' import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card' import { Separator } from '@/components/ui/separator' type DrupalArticle = { id: string attributes?: { title?: string status?: boolean created?: string } } type DrupalCollectionResponse = { data: T[] } type DrupalJsonApiEntryPoint = { links: Record } function App() { const [articles, setArticles] = useState([]) const [resourcePath, setResourcePath] = useState(null) const [isLoading, setIsLoading] = useState(true) const [error, setError] = useState(null) useEffect(() => { const loadArticles = async () => { try { setIsLoading(true) setError(null) const entryPoint = await fetchDrupalResource('') const nodeResources = Object.keys(entryPoint.links).filter((key) => key.startsWith('node--')) if (nodeResources.length === 0) { throw new Error('No node resources found in JSON:API. Create a content type (for example Article) and ensure JSON:API is enabled.') } const selectedNodeResource = nodeResources.includes('node--article') ? 'node--article' : nodeResources[0] const selectedPath = `/${selectedNodeResource.replace('--', '/')}` setResourcePath(selectedPath) const response = await fetchDrupalResource>(selectedPath) setArticles(response.data) } catch (loadError) { const message = loadError instanceof Error ? loadError.message : 'Failed to load articles from Drupal.' setError(message) } finally { setIsLoading(false) } } void loadArticles() }, []) const articleCount = articles.length const formatDate = (value?: string) => { if (!value) { return 'Unknown date' } return new Date(value).toLocaleString() } return (
Portfolio CMS Homepage This homepage now uses shadcn/ui components and reads content from Drupal JSON:API. {isLoading ? 'Loading' : error ? 'Error' : 'Connected'} Articles: {articleCount} {resourcePath && Resource: {resourcePath}} Headless Drupal + Vite + shadcn/ui {error && ( Could not fetch articles {error} )} {!isLoading && !error && articleCount === 0 && ( No articles found Connected to Drupal successfully, but this resource currently has no content. )} {!isLoading && !error && articleCount > 0 && (
{articles.map((article) => ( {article.attributes?.title ?? '(Untitled)'} {article.id}
Status {article.attributes?.status ? 'Published' : 'Unpublished'}
Created {formatDate(article.attributes?.created)}
))}
)}
) } export default App