series building

This commit is contained in:
Nicolas Cantu 2026-01-06 00:37:49 +01:00
parent 758ab5c966
commit ba0fcbfc96
8 changed files with 72 additions and 46 deletions

View File

@ -1,4 +1,4 @@
import React from 'react' import { t } from '@/lib/i18n'
type DocSection = 'user-guide' | 'faq' | 'publishing' | 'payment' type DocSection = 'user-guide' | 'faq' | 'publishing' | 'payment'
@ -18,7 +18,7 @@ export function DocsSidebar({ docs, selectedDoc, onSelectDoc }: DocsSidebarProps
return ( return (
<aside className="lg:w-64 flex-shrink-0"> <aside className="lg:w-64 flex-shrink-0">
<div className="bg-cyber-dark border border-neon-cyan/20 rounded-lg p-4 sticky top-4 backdrop-blur-sm"> <div className="bg-cyber-dark border border-neon-cyan/20 rounded-lg p-4 sticky top-4 backdrop-blur-sm">
<h2 className="text-lg font-bold mb-4 text-neon-cyan font-mono">Documentation</h2> <h2 className="text-lg font-bold mb-4 text-neon-cyan font-mono">{t('docs.title')}</h2>
<nav className="space-y-2"> <nav className="space-y-2">
{docs.map((doc) => ( {docs.map((doc) => (
<button <button

View File

@ -3,19 +3,21 @@ import { useNostrAuth } from '@/hooks/useNostrAuth'
export function KeyIndicator() { export function KeyIndicator() {
const { pubkey, isUnlocked } = useNostrAuth() const { pubkey, isUnlocked } = useNostrAuth()
// No indicator if no account
if (!pubkey) {
return null
}
// Red if private key is accessible (unlocked) // Red if private key is accessible (unlocked)
// Green if only public key is accessible (connected but not unlocked) // Green if only public key is accessible (connected but not unlocked)
const color = isUnlocked ? 'text-red-500' : 'text-green-500' const color = isUnlocked ? 'text-red-500' : 'text-green-500'
const title = isUnlocked ? 'Private key accessible' : 'Public key accessible' const title = isUnlocked ? 'Private key accessible' : pubkey ? 'Public key accessible' : 'Repository Git'
return ( return (
<span className={`ml-2 text-xl ${color}`} title={title}> <a
href="https://git.4nkweb.com/4nk/story-research-zapwall"
target="_blank"
rel="noopener noreferrer"
className={`ml-2 text-xl ${color} hover:opacity-80 transition-opacity cursor-pointer`}
title={title}
onClick={(e) => e.stopPropagation()}
>
🔑 🔑
</span> </a>
) )
} }

View File

@ -21,19 +21,22 @@ export function PageHeader() {
return ( return (
<header className="bg-cyber-dark border-b border-neon-cyan/30 shadow-glow-cyan"> <header className="bg-cyber-dark border-b border-neon-cyan/30 shadow-glow-cyan">
<div className="max-w-4xl mx-auto px-4 py-4 flex justify-between items-center"> <div className="max-w-4xl mx-auto px-4 py-4 flex justify-between items-center">
<Link href="/" className="text-2xl font-bold text-neon-cyan text-glow-cyan font-mono hover:text-neon-green transition-colors flex items-center gap-2"> <div className="flex items-center gap-2">
{t('home.title')} <Link href="/" className="text-2xl font-bold text-neon-cyan text-glow-cyan font-mono hover:text-neon-green transition-colors">
{t('home.title')}
</Link>
<a <a
href="https://git.4nkweb.com/4nk/story-research-zapwall" href="https://git.4nkweb.com/4nk/story-research-zapwall"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="text-cyber-accent hover:text-neon-cyan transition-colors" className="text-cyber-accent hover:text-neon-cyan transition-colors"
title="Repository Git" title="Repository Git"
onClick={(e) => e.stopPropagation()}
> >
<GitIcon /> <GitIcon />
</a> </a>
<KeyIndicator /> <KeyIndicator />
</Link> </div>
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
<LanguageSelector /> <LanguageSelector />
<Link <Link
@ -42,12 +45,6 @@ export function PageHeader() {
> >
{t('nav.documentation')} {t('nav.documentation')}
</Link> </Link>
<Link
href="/settings"
className="px-4 py-2 text-cyber-accent hover:text-neon-cyan text-sm font-medium transition-colors border border-cyber-accent/30 hover:border-neon-cyan/50 rounded hover:shadow-glow-cyan"
>
Settings
</Link>
<ConditionalPublishButton /> <ConditionalPublishButton />
</div> </div>
</div> </div>

View File

@ -26,10 +26,14 @@ export function useDocs(docs: DocLink[]) {
const text = await response.text() const text = await response.text()
setDocContent(text) setDocContent(text)
} else { } else {
setDocContent('# Erreur\n\nImpossible de charger la documentation.') // Import t dynamically to avoid circular dependency
const { t } = await import('@/lib/i18n')
setDocContent(`# ${t('docs.error')}\n\n${t('docs.error.loadFailed')}`)
} }
} catch { } catch {
setDocContent('# Erreur\n\nImpossible de charger la documentation.') // Import t dynamically to avoid circular dependency
const { t } = await import('@/lib/i18n')
setDocContent(`# ${t('docs.error')}\n\n${t('docs.error.loadFailed')}`)
} finally { } finally {
setLoading(false) setLoading(false)
} }
@ -37,6 +41,7 @@ export function useDocs(docs: DocLink[]) {
useEffect(() => { useEffect(() => {
loadDoc('user-guide') loadDoc('user-guide')
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []) }, [])
return { return {
@ -46,4 +51,3 @@ export function useDocs(docs: DocLink[]) {
loadDoc, loadDoc,
} }
} }

View File

@ -38,6 +38,9 @@ export async function buildPresentationEvent(
// Build URL: https://zapwall.fr/author/<hash>_<index>_<version> // Build URL: https://zapwall.fr/author/<hash>_<index>_<version>
const profileUrl = generateObjectUrl('author', hashId, index, version) const profileUrl = generateObjectUrl('author', hashId, index, version)
// Encode pubkey to npub (for metadata JSON)
const npub = nip19.npubEncode(authorPubkey)
// Build visible content message // Build visible content message
const visibleContent = [ const visibleContent = [
'Nouveau profil publié sur zapwall.fr', 'Nouveau profil publié sur zapwall.fr',

View File

@ -18,6 +18,16 @@ nav.publish=Publish profile
nav.createAuthorPage=Create author page nav.createAuthorPage=Create author page
nav.loading=Loading... nav.loading=Loading...
# Documentation
docs.title=Documentation
docs.userGuide=User Guide
docs.faq=FAQ
docs.publishing=Publishing Guide
docs.payment=Payment Guide
docs.error=Error
docs.error.loadFailed=Unable to load documentation.
docs.meta.description=Complete documentation for zapwall.fr
# Categories # Categories
category.science-fiction=Science Fiction category.science-fiction=Science Fiction
category.scientific-research=Scientific Research category.scientific-research=Scientific Research

View File

@ -18,6 +18,16 @@ nav.publish=Publier le profil
nav.createAuthorPage=Créer page auteur nav.createAuthorPage=Créer page auteur
nav.loading=Chargement... nav.loading=Chargement...
# Documentation
docs.title=Documentation
docs.userGuide=Guide d'utilisation
docs.faq=FAQ
docs.publishing=Guide de publication
docs.payment=Guide de paiement
docs.error=Erreur
docs.error.loadFailed=Impossible de charger la documentation.
docs.meta.description=Documentation complète pour zapwall.fr
# Categories # Categories
category.science-fiction=Science-fiction category.science-fiction=Science-fiction
category.scientific-research=Recherche scientifique category.scientific-research=Recherche scientifique

View File

@ -14,37 +14,37 @@ interface DocLink {
file: string file: string
} }
const docs: DocLink[] = [
{
id: 'user-guide',
title: 'Guide d\'utilisation',
file: 'user-guide.md',
},
{
id: 'faq',
title: 'FAQ',
file: 'faq.md',
},
{
id: 'publishing',
title: 'Guide de publication',
file: 'publishing-guide.md',
},
{
id: 'payment',
title: 'Guide de paiement',
file: 'payment-guide.md',
},
]
export default function DocsPage() { export default function DocsPage() {
const docs: DocLink[] = [
{
id: 'user-guide',
title: t('docs.userGuide'),
file: 'user-guide.md',
},
{
id: 'faq',
title: t('docs.faq'),
file: 'faq.md',
},
{
id: 'publishing',
title: t('docs.publishing'),
file: 'publishing-guide.md',
},
{
id: 'payment',
title: t('docs.payment'),
file: 'payment-guide.md',
},
]
const { selectedDoc, docContent, loading, loadDoc } = useDocs(docs) const { selectedDoc, docContent, loading, loadDoc } = useDocs(docs)
return ( return (
<> <>
<Head> <Head>
<title>{t('nav.documentation')} - zapwall.fr</title> <title>{t('nav.documentation')} - zapwall.fr</title>
<meta name="description" content="Documentation complète pour zapwall.fr" /> <meta name="description" content={t('docs.meta.description')} />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.svg" type="image/svg+xml" /> <link rel="icon" href="/favicon.svg" type="image/svg+xml" />
</Head> </Head>