diff --git a/app/paroles/[slug]/page.js b/app/paroles/[slug]/page.js
new file mode 100644
index 0000000..0a8f1eb
--- /dev/null
+++ b/app/paroles/[slug]/page.js
@@ -0,0 +1,105 @@
+import {notFound} from 'next/navigation'
+import Box from '@mui/material/Box'
+
+import {jwennTeksEpiSlug} from '../../../lib/oki-api'
+import AnTeks from '../../../components/teks/an-teks'
+import {getAlias} from '../../../lib/utils/format'
+import {formatKuveti} from '../../../lib/kuveti'
+
+const apiUrl = process.env.NEXT_PUBLIC_API_URL_ROOT || 'http://localhost:1337'
+const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3000'
+const drawerWidth = 340
+
+async function jwennAnTeks(slug) {
+ const teks = await jwennTeksEpiSlug(slug)
+
+ if (!teks) {
+ notFound()
+ }
+
+ return teks
+}
+
+export async function generateMetadata({params}) {
+ const {slug} = params
+
+ const anTeks = await jwennAnTeks(slug)
+
+ const awtis = anTeks.attributes.artistes.length === 1 ? anTeks.attributes.artistes[0].data.attributes.alias : getAlias(anTeks.attributes.artistes, anTeks.attributes.prioriteArtistes)
+ const title = `OKI | ${awtis} - ${anTeks.attributes.titre} | Paroles et Traductions`
+ const description = `Paroles de « ${anTeks?.attributes?.titre} » : ${anTeks?.attributes?.transcription.slice(0, 100)}...`
+ const url = `${siteUrl}/${slug}`
+
+ const {couverture} = anTeks.attributes
+ const kuvetiFormat = formatKuveti(couverture)
+
+ return {
+ title,
+ description,
+ openGraph: {
+ title,
+ description,
+ url,
+ siteName: title,
+ images: [
+ {
+ url: `${apiUrl}${kuvetiFormat?.url}`,
+ width: kuvetiFormat?.width,
+ height: kuvetiFormat?.height
+ }
+ ],
+ locale: 'fr_FR',
+ type: 'website'
+ },
+ twitter: {
+ site: '@OrganisationKA',
+ card: 'summary_large_image',
+ title,
+ description,
+ creator: '@OrganisationKA',
+ images: {
+ url: `${apiUrl}${kuvetiFormat?.url}`,
+ alt: `Couverture ${title}`,
+ }
+ }
+ }
+}
+
+export default async function AnPawolPaj({params}) {
+ const {slug} = params
+
+ const anTeks = await jwennAnTeks(slug)
+
+ const jsonLd = {
+ '@context': 'http://schema.org',
+ '@type': 'MusicRecording',
+ name: anTeks.attributes.titre,
+ url: `${siteUrl}/paroles/${slug}`,
+ byArtist: anTeks.attributes.artistes.data.map(({attributes}) => ({
+ '@type': 'Person',
+ name: attributes.alias,
+ url: `${siteUrl}/awtis/${attributes.slug}`
+ })),
+ datePublished: anTeks.attributes?.annee
+ }
+
+ return (
+ <>
+
+
+
+
+
+
+
+ >
+ )
+}
diff --git a/app/paroles/layout.js b/app/paroles/layout.js
new file mode 100644
index 0000000..2f98996
--- /dev/null
+++ b/app/paroles/layout.js
@@ -0,0 +1,61 @@
+import {Suspense} from 'react'
+import {notFound} from 'next/navigation'
+import {jwennTeks} from '../../lib/oki-api'
+import TeksDrawer from '../../components/teks/teks-drawer'
+import Loading from './loading'
+
+export const metadata = {
+ title: 'OKI | Organisation KA Internationale. Paroles et traductions.',
+ description: 'Retrouvez les paroles et les traductions de vos chansons préférées.',
+ openGraph: {
+ title: 'OKI | Organisation KA Internationale. Paroles et traductions.',
+ description: 'Retrouvez les paroles et les traductions de vos chansons préférées.',
+ url: 'https://oki.re/paroles',
+ siteName: 'OKI | Organisation KA Internationale. Paroles et traductions.',
+ images: [
+ {
+ url: 'htts://oki.re/logo-512x512.png',
+ width: 512,
+ height: 512
+ }
+ ],
+ locale: 'fr_FR',
+ type: 'website'
+ },
+ twitter: {
+ site: '@OrganisationKA',
+ card: 'summary_large_image',
+ title: 'OKI | Organisation KA Internationale. Paroles et traductions.',
+ description: 'Retrouvez les paroles et les traductions de vos chansons préférées.',
+ creator: '@OrganisationKA',
+ images: {
+ url: 'https://oki.re/logo-512x512.png',
+ alt: 'OKI Logo',
+ },
+ }
+}
+
+async function jwennDotDone() {
+ const teks = await jwennTeks()
+
+ if (!teks) {
+ notFound()
+ }
+
+ return teks
+}
+
+export default async function PawolLayout({children}) {
+ const teks = await jwennDotDone()
+
+ return (
+ <>
+ }>
+
+
+
+ >
+ )
+}
diff --git a/app/paroles/loading.js b/app/paroles/loading.js
new file mode 100644
index 0000000..3df6ceb
--- /dev/null
+++ b/app/paroles/loading.js
@@ -0,0 +1,17 @@
+import Skeleton from '@mui/material/Skeleton'
+import Box from '@mui/material/Box'
+
+const drawerWidth = 240
+
+export default function Loading() {
+ return (
+
+
+
+
+
+ )
+}
diff --git a/app/paroles/page.js b/app/paroles/page.js
new file mode 100644
index 0000000..e5ad379
--- /dev/null
+++ b/app/paroles/page.js
@@ -0,0 +1,32 @@
+import Box from '@mui/material/Box'
+import {notFound} from 'next/navigation'
+
+import {jwennDenyeTeks} from '../../lib/oki-api'
+import DenyeTeks from '../../components/teks/denye-teks'
+
+const drawerWidth = 240
+
+async function jwennDone() {
+ const denyeTeks = await jwennDenyeTeks()
+
+ if (!denyeTeks) {
+ notFound()
+ }
+
+ return denyeTeks
+}
+
+export default async function PawolPaj() {
+ const denyeTeks = await jwennDone()
+
+ return (
+
+
+
+
+
+ )
+}
diff --git a/pages/paroles/[slug].js b/pages/paroles/[slug].js
deleted file mode 100644
index f4cd7e4..0000000
--- a/pages/paroles/[slug].js
+++ /dev/null
@@ -1,96 +0,0 @@
-import PropTypes from 'prop-types'
-
-import {getAlias} from '../../lib/utils/format'
-import {jwennTeksEpiSlug} from '../../lib/oki-api'
-
-import HeadLayout from '../../components/head-layout'
-import TeksDrawer from '../../components/teks/teks-drawer'
-
-import Custom500 from '../500'
-import Custom404 from '../404'
-
-export default function SlugTeks({hasError, errorMessage, parole, slug}) {
- if (hasError) {
- console.log('⚠️ error :', errorMessage)
- return
- }
-
- if (!parole) {
- return
- }
-
- const summary = `Paroles de « ${parole?.attributes?.titre} » : ${parole?.attributes?.transcription.slice(0, 100)}...`
-
- const artistes = parole.attributes.artistes.length === 1 ? parole.attributes.artistes[0].data.attributes.alias : getAlias(parole.attributes.artistes, parole.attributes.prioriteArtistes)
- const {couverture} = parole.attributes
- const formatKouveti = () => {
- if (!couverture?.data?.attributes) {
- return null
- }
-
- if (couverture.data.attributes && couverture.data.attributes.formats && couverture.data.attributes.formats.large) {
- return couverture.data.attributes.formats.large
- }
-
- if (couverture.data.attributes && couverture.data.attributes.formats && couverture.data.attributes.formats.medium) {
- return couverture.data.attributes.formats.medium
- }
-
- if (couverture.data.attributes && couverture.data.attributes.formats && couverture.data.attributes.formats.small) {
- return couverture.data.attributes.formats.small
- }
-
- return couverture.data.attributes
- }
-
- return (
-
-
-
- )
-}
-
-export async function getServerSideProps({query}) {
- const {slug} = query
- let paroles
- let parole
- let hasError
- let errorMessage
-
- try {
- parole = await jwennTeksEpiSlug(slug)
- } catch (error) {
- errorMessage = error
- hasError = true
- }
-
- return {
- props: {
- hasError: hasError || null,
- errorMessage: errorMessage ? errorMessage.message : null,
- paroles: paroles || null,
- parole: parole || null,
- slug
- }
- }
-}
-
-SlugTeks.defaultProps = {
- hasError: null,
- errorMessage: null,
- parole: null
-}
-
-SlugTeks.propTypes = {
- hasError: PropTypes.bool,
- errorMessage: PropTypes.string,
- parole: PropTypes.object,
- slug: PropTypes.string.isRequired,
-}
diff --git a/pages/paroles/index.js b/pages/paroles/index.js
deleted file mode 100644
index affeada..0000000
--- a/pages/paroles/index.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import PropTypes from 'prop-types'
-
-import {jwennDenyeTeks} from '../../lib/oki-api'
-
-import HeadLayout from '../../components/head-layout'
-
-import Custom500 from '../500'
-import TeksDrawer from '../../components/teks/teks-drawer'
-
-export default function Teks({errorCode, errorMessage, denyeTeks}) {
- if (errorCode) {
- console.log('⚠️ error', errorMessage)
- return
- }
-
- return (
-
-
-
- )
-}
-
-export async function getServerSideProps() {
- let denyeTeks
- let hasError
- let errorMessage
-
- try {
- denyeTeks = await jwennDenyeTeks()
- } catch (error) {
- errorMessage = error.message
- hasError = true
- }
-
- return {
- props: {
- errorCode: hasError || null,
- errorMessage: errorMessage || null,
- denyeTeks: denyeTeks || null
- }
- }
-}
-
-Teks.defaultProps = {
- errorCode: null,
- errorMessage: null,
- denyeTeks: null
-}
-
-Teks.propTypes = {
- errorCode: PropTypes.bool,
- errorMessage: PropTypes.string,
- denyeTeks: PropTypes.array
-}