@@ -65,25 +67,44 @@ function SponsoringSummary({ totalSponsoring }: { totalSponsoring: number }) {
)
}
-function SeriesList({ series }: { series: Series[]; authorPubkey: string }) {
- if (series.length === 0) {
- return (
-
- )
- }
+function SeriesList({ series, authorPubkey, onSeriesCreated }: { series: Series[]; authorPubkey: string; onSeriesCreated: () => void }) {
+ const { pubkey, isUnlocked } = useNostrAuth()
+ const [showCreateModal, setShowCreateModal] = useState(false)
+ const isAuthor = pubkey === authorPubkey && isUnlocked
return (
-
{t('series.title')}
-
- {series.map((s) => (
-
-
{}} />
-
- ))}
+
+
{t('series.title')}
+ {isAuthor && (
+
+ )}
+ {series.length === 0 ? (
+
+ ) : (
+
+ {series.map((s) => (
+
+ {}} />
+
+ ))}
+
+ )}
+ setShowCreateModal(false)}
+ onSuccess={onSeriesCreated}
+ authorPubkey={authorPubkey}
+ />
)
}
@@ -110,31 +131,31 @@ function useAuthorData(authorPubkey: string) {
const [loading, setLoading] = useState(true)
const [error, setError] = useState
(null)
- useEffect(() => {
+ const reload = async () => {
if (!authorPubkey) {
return
}
- const load = async () => {
- setLoading(true)
- setError(null)
+ setLoading(true)
+ setError(null)
- try {
- const { pres, seriesList, sponsoring } = await loadAuthorData(authorPubkey)
- setPresentation(pres)
- setSeries(seriesList)
- setTotalSponsoring(sponsoring)
- } catch (e) {
- setError(e instanceof Error ? e.message : 'Erreur lors du chargement')
- } finally {
- setLoading(false)
- }
+ try {
+ const { pres, seriesList, sponsoring } = await loadAuthorData(authorPubkey)
+ setPresentation(pres)
+ setSeries(seriesList)
+ setTotalSponsoring(sponsoring)
+ } catch (e) {
+ setError(e instanceof Error ? e.message : 'Erreur lors du chargement')
+ } finally {
+ setLoading(false)
}
+ }
- void load()
+ useEffect(() => {
+ void reload()
}, [authorPubkey])
- return { presentation, series, totalSponsoring, loading, error }
+ return { presentation, series, totalSponsoring, loading, error, reload }
}
function AuthorPageContent({
@@ -144,6 +165,7 @@ function AuthorPageContent({
authorPubkey,
loading,
error,
+ onSeriesCreated,
}: {
presentation: AuthorPresentationArticle | null
series: Series[]
@@ -151,6 +173,7 @@ function AuthorPageContent({
authorPubkey: string
loading: boolean
error: string | null
+ onSeriesCreated: () => void
}) {
if (loading) {
return {t('common.loading')}
@@ -165,7 +188,7 @@ function AuthorPageContent({
<>
-
+
>
)
}
@@ -181,7 +204,7 @@ export default function AuthorPage() {
const router = useRouter()
const { pubkey } = router.query
const authorPubkey = typeof pubkey === 'string' ? pubkey : ''
- const { presentation, series, totalSponsoring, loading, error } = useAuthorData(authorPubkey)
+ const { presentation, series, totalSponsoring, loading, error, reload } = useAuthorData(authorPubkey)
if (!authorPubkey) {
return null
@@ -204,6 +227,7 @@ export default function AuthorPage() {
authorPubkey={authorPubkey}
loading={loading}
error={error}
+ onSeriesCreated={reload}
/>
diff --git a/pages/docs.tsx b/pages/docs.tsx
index 875b03e..0a63f0d 100644
--- a/pages/docs.tsx
+++ b/pages/docs.tsx
@@ -3,17 +3,9 @@ import { DocsSidebar } from '@/components/DocsSidebar'
import { DocsContent } from '@/components/DocsContent'
import { PageHeader } from '@/components/PageHeader'
import { Footer } from '@/components/Footer'
-import { useDocs } from '@/hooks/useDocs'
+import { useDocs, type DocLink, type DocSection } from '@/hooks/useDocs'
import { t } from '@/lib/i18n'
-type DocSection = 'user-guide' | 'faq' | 'publishing' | 'payment'
-
-interface DocLink {
- id: DocSection
- title: string
- file: string
-}
-
export default function DocsPage() {
const docs: DocLink[] = [
{
@@ -36,6 +28,11 @@ export default function DocsPage() {
title: t('docs.payment'),
file: 'payment-guide.md',
},
+ {
+ id: 'fees-and-contributions',
+ title: t('docs.feesAndContributions'),
+ file: 'fees-and-contributions.md',
+ },
]
const { selectedDoc, docContent, loading, loadDoc } = useDocs(docs)
@@ -55,7 +52,7 @@ export default function DocsPage() {
{
+ onSelectDoc={(slug: DocSection) => {
void loadDoc(slug)
}}
/>
diff --git a/public/locales/en.txt b/public/locales/en.txt
index 1414931..d658a04 100644
--- a/public/locales/en.txt
+++ b/public/locales/en.txt
@@ -11,6 +11,7 @@ home.funding.target=Target: {{target}} BTC
home.funding.current=Raised: {{current}} BTC
home.funding.progress={{percent}}% of funding reached
home.funding.description=Funds collected by the platform serve the development of free AI features for authors (development and hardware).
+home.funding.certification.title=Certification on a Bitcoin-anchored signet of intellectual property
# Navigation
nav.documentation=Documentation
@@ -18,12 +19,17 @@ nav.publish=Publish profile
nav.createAuthorPage=Create author page
nav.loading=Loading...
+# Connect
+connect.createAccount=Create account
+connect.connect=Connect
+
# Documentation
docs.title=Documentation
docs.userGuide=User Guide
docs.faq=FAQ
docs.publishing=Publishing Guide
docs.payment=Payment Guide
+docs.feesAndContributions=Fees and Contributions
docs.error=Error
docs.error.loadFailed=Unable to load documentation.
docs.meta.description=Complete documentation for zapwall.fr
@@ -48,6 +54,19 @@ series.empty=No series published yet.
series.view=View series
series.publications=Series publications
series.publications.empty=No publications for this series.
+series.create.button=Create a series
+series.create.title=Create a new series
+series.create.submit=Create series
+series.create.field.title=Series title
+series.create.field.description=Series description
+series.create.field.preview=Preview of publication content
+series.create.field.preview.help=This preview will be visible to everyone to give a taste of the series content
+series.create.field.category=Publication type
+series.create.field.cover=Cover image
+series.create.field.cover.help=Cover image for the series (optional, max 5MB, formats: PNG, JPG, WebP)
+series.create.error.notAuthor=You must be the author of this page and have unlocked your account to create a series
+series.create.error.missingFields=Please fill in all required fields
+series.create.error.publishFailed=Error publishing series
# Author page
author.title=Author page
@@ -57,6 +76,7 @@ author.sponsoring.total=Total received: {{amount}} BTC
author.sponsoring.sats=In satoshis: {{amount}} sats
author.notFound=Author page not found.
author.profileNote=This profile data is specific to zapwall.fr and may differ from your Nostr profile.
+author.profilePicture=Profile picture
# Publish
publish.title=Publish a new publication
@@ -120,6 +140,19 @@ footer.privacy=Privacy Policy
common.loading=Loading...
common.loading.articles=Loading articles...
common.loading.authors=Loading authors...
+common.edit=Edit
+common.delete=Delete
+common.confirmDelete=Confirm delete
+common.cancel=Cancel
+
+# Search
+search.clear=Clear search
+
+# Upload
+upload.error.failed=Upload failed
+
+# Notification
+notification.delete=Delete notification
common.error=Error
common.error.noContent=No content found
common.empty.articles=No articles found. Check back later!
diff --git a/public/locales/fr.txt b/public/locales/fr.txt
index 3d75f26..5f1f25e 100644
--- a/public/locales/fr.txt
+++ b/public/locales/fr.txt
@@ -11,6 +11,7 @@ home.funding.target=Cible : {{target}} BTC
home.funding.current=Collecté : {{current}} BTC
home.funding.progress={{percent}}% du financement atteint
home.funding.description=Les fonds collectés par la plateforme servent au développement de fonctions IA gratuites pour les auteurs (développement et matériel).
+home.funding.certification.title=Certification sur un signet ancré sur Bitcoin de la propriété intellectuelle
# Navigation
nav.documentation=Documentation
@@ -18,12 +19,17 @@ nav.publish=Publier le profil
nav.createAuthorPage=Créer page auteur
nav.loading=Chargement...
+# Connect
+connect.createAccount=Créer un compte
+connect.connect=Se connecter
+
# Documentation
docs.title=Documentation
docs.userGuide=Guide d'utilisation
docs.faq=FAQ
docs.publishing=Guide de publication
docs.payment=Guide de paiement
+docs.feesAndContributions=Frais et contributions
docs.error=Erreur
docs.error.loadFailed=Impossible de charger la documentation.
docs.meta.description=Documentation complète pour zapwall.fr
@@ -48,6 +54,19 @@ series.empty=Aucune série publiée pour le moment.
series.view=Voir la série
series.publications=Publications de la série
series.publications.empty=Aucune publication pour cette série.
+series.create.button=Créer une série
+series.create.title=Créer une nouvelle série
+series.create.submit=Créer la série
+series.create.field.title=Titre de la série
+series.create.field.description=Description de la série
+series.create.field.preview=Aperçu du contenu d'une publication
+series.create.field.preview.help=Cet aperçu sera visible par tous pour donner un avant-goût du contenu de la série
+series.create.field.category=Type de publication
+series.create.field.cover=Image de couverture
+series.create.field.cover.help=Image de couverture pour la série (optionnel, max 5Mo, formats: PNG, JPG, WebP)
+series.create.error.notAuthor=Vous devez être l'auteur de cette page et avoir déverrouillé votre compte pour créer une série
+series.create.error.missingFields=Veuillez remplir tous les champs obligatoires
+series.create.error.publishFailed=Erreur lors de la publication de la série
# Author page
author.title=Page auteur
@@ -57,6 +76,7 @@ author.sponsoring.total=Total reçu : {{amount}} BTC
author.sponsoring.sats=En satoshis : {{amount}} sats
author.notFound=Page auteur introuvable.
author.profileNote=Les données de ce profil sont spécifiques à zapwall.fr et peuvent différer de votre profil Nostr.
+author.profilePicture=Photo de profil
# Publish
publish.title=Publier une nouvelle publication
@@ -120,6 +140,19 @@ footer.privacy=Politique de confidentialité
common.loading=Chargement...
common.loading.articles=Chargement des articles...
common.loading.authors=Chargement des auteurs...
+common.edit=Modifier
+common.delete=Supprimer
+common.confirmDelete=Confirmer la suppression
+common.cancel=Annuler
+
+# Search
+search.clear=Effacer la recherche
+
+# Upload
+upload.error.failed=Échec du téléchargement
+
+# Notification
+notification.delete=Supprimer la notification
common.error=Erreur
common.error.noContent=Aucun contenu trouvé
common.empty.articles=Aucun article trouvé. Revenez plus tard !