diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 00bf450f..f481b831 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -88,6 +88,7 @@ jobs: cat < apps/web/.env NEXT_PUBLIC_SITE_URL="${{ secrets.INFISICAL_WEB_APP_URL }}" NEXT_PUBLIC_API_URL="${{ secrets.INFISICAL_API_URL }}" + NEXT_PUBLIC_GOOGLE_ADSENSE_CLIENT_ID="${{ secrets.INFISICAL_GOOGLE_ADSENSE_CLIENT_ID }}" NEXT_PUBLIC_REVENUECAT_API_KEY="${{ secrets.INFISICAL_REVENUECAT_WEB_API_KEY }}" NEXT_PUBLIC_FIREBASE_API_KEY="${{ secrets.INFISICAL_FIREBASE_API_KEY }}" NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN="${{ secrets.INFISICAL_FIREBASE_AUTH_DOMAIN }}" diff --git a/apps/web/.env.template b/apps/web/.env.template index dc06d714..4feb3b4f 100644 --- a/apps/web/.env.template +++ b/apps/web/.env.template @@ -4,6 +4,8 @@ NEXT_PUBLIC_API_URL= # ---------------------------------------------------------------------------- # # --------------------------------- SERVICES --------------------------------- # +# ADS +NEXT_PUBLIC_GOOGLE_ADSENSE_CLIENT_ID= # ANALYTICS ANALYTICS_URL= ANALYTICS_ID= diff --git a/apps/web/src/app/[lang]/(app)/about/page.tsx b/apps/web/src/app/[lang]/(app)/about/page.tsx index c064bf9c..821e3187 100644 --- a/apps/web/src/app/[lang]/(app)/about/page.tsx +++ b/apps/web/src/app/[lang]/(app)/about/page.tsx @@ -4,6 +4,7 @@ import { Link } from '@/lib/i18n/navigation'; import { upperFirst } from 'lodash'; import { Metadata } from 'next'; import { SupportedLocale } from '@libs/i18n'; +import { ConsentButton } from '@/components/Ads/ConsentButton'; export const generateMetadata = async (props: { params: Promise<{ @@ -163,6 +164,20 @@ const About = async (props: {

{t('pricing.intro')}

{t('pricing.subdescription')}

+ + {/* BUSINESS MODEL */}

diff --git a/apps/web/src/app/[lang]/(app)/film/[film_id]/(default)/_components/MovieAds.tsx b/apps/web/src/app/[lang]/(app)/film/[film_id]/(default)/_components/MovieAds.tsx new file mode 100644 index 00000000..bf1ad083 --- /dev/null +++ b/apps/web/src/app/[lang]/(app)/film/[film_id]/(default)/_components/MovieAds.tsx @@ -0,0 +1,12 @@ +'use client'; + +import AdBanner from '@/components/Ads/AdBanner'; +import { useAuth } from '@/context/auth-context'; + +export const MovieAds = () => { + const { session } = useAuth(); + + if (session) return null; + + return ; +}; diff --git a/apps/web/src/app/[lang]/(app)/film/[film_id]/(default)/page.tsx b/apps/web/src/app/[lang]/(app)/film/[film_id]/(default)/page.tsx index 6c687bc8..528b7b99 100644 --- a/apps/web/src/app/[lang]/(app)/film/[film_id]/(default)/page.tsx +++ b/apps/web/src/app/[lang]/(app)/film/[film_id]/(default)/page.tsx @@ -12,37 +12,42 @@ import { getMovie } from '@/api/server/medias'; import { getTmdbImage } from '@/lib/tmdb/getTmdbImage'; import { JustWatchWidget } from '@/components/JustWatch/JustWatchWidgetScript'; import { MovieCasting } from './_components/MovieCasting'; +import { MovieAds } from './_components/MovieAds'; -export async function generateMetadata( - props: { - params: Promise<{ - lang: SupportedLocale; - film_id: string; - }>; - } -): Promise { +export async function generateMetadata(props: { + params: Promise<{ + lang: SupportedLocale; + film_id: string; + }>; +}): Promise { const { lang, film_id } = await props.params; const t = await getTranslations({ locale: lang as SupportedLocale }); - const { id: movieId} = getIdFromSlug(film_id); + const { id: movieId } = getIdFromSlug(film_id); const { data: movie, error } = await getMovie(lang, movieId); if (error || !movie) { return { title: upperFirst(t('common.messages.film_not_found')) }; } return { - title: t('pages.film.metadata.title', { title: movie.title!, year: new Date(String(movie.releaseDate)).getFullYear() }), + title: t('pages.film.metadata.title', { + title: movie.title!, + year: new Date(String(movie.releaseDate)).getFullYear(), + }), description: truncate( movie.directors ? t('pages.film.metadata.description', { - title: movie.title!, - directors: new Intl.ListFormat(lang, { style: 'long', type: 'conjunction' }).format(movie.directors.map((director) => director.name ?? '')), - year: new Date(String(movie.releaseDate)).getFullYear(), - overview: movie.overview || '', - }) : t('pages.film.metadata.description_no_director', { - title: movie.title!, - year: new Date(String(movie.releaseDate)).getFullYear(), - overview: movie.overview || '' - }), - { length: siteConfig.seo.description.limit } + title: movie.title!, + directors: new Intl.ListFormat(lang, { style: 'long', type: 'conjunction' }).format( + movie.directors.map((director) => director.name ?? ''), + ), + year: new Date(String(movie.releaseDate)).getFullYear(), + overview: movie.overview || '', + }) + : t('pages.film.metadata.description_no_director', { + title: movie.title!, + year: new Date(String(movie.releaseDate)).getFullYear(), + overview: movie.overview || '', + }), + { length: siteConfig.seo.description.limit }, ), alternates: generateAlternates(lang, `/film/${movie.slug}`), openGraph: { @@ -51,35 +56,36 @@ export async function generateMetadata( description: truncate( movie.directors ? t('pages.film.metadata.description', { - title: movie.title!, - directors: new Intl.ListFormat(lang, { style: 'long', type: 'conjunction' }).format(movie.directors.map((director) => director.name ?? '')), - year: new Date(String(movie.releaseDate)).getFullYear(), - overview: movie.overview || '', - }) : t('pages.film.metadata.description_no_director', { - title: movie.title!, - year: new Date(String(movie.releaseDate)).getFullYear(), - overview: movie.overview || '' - }), - { length: siteConfig.seo.description.limit } + title: movie.title!, + directors: new Intl.ListFormat(lang, { style: 'long', type: 'conjunction' }).format( + movie.directors.map((director) => director.name ?? ''), + ), + year: new Date(String(movie.releaseDate)).getFullYear(), + overview: movie.overview || '', + }) + : t('pages.film.metadata.description_no_director', { + title: movie.title!, + year: new Date(String(movie.releaseDate)).getFullYear(), + overview: movie.overview || '', + }), + { length: siteConfig.seo.description.limit }, ), url: `${siteConfig.url}/${lang}/film/${movie.slug}`, - images: movie.posterPath ? [ - { url: getTmdbImage({ path: movie.posterPath, size: 'w500' }) }, - ] : undefined, + images: movie.posterPath + ? [{ url: getTmdbImage({ path: movie.posterPath, size: 'w500' }) }] + : undefined, type: 'video.movie', locale: lang, - } + }, }; } -export default async function MoviePage( - props: { - params: Promise<{ - lang: SupportedLocale; - film_id: string; - }>; - } -) { +export default async function MoviePage(props: { + params: Promise<{ + lang: SupportedLocale; + film_id: string; + }>; +}) { const { lang, film_id } = await props.params; const t = await getTranslations(); const { id: movieId } = getIdFromSlug(film_id); @@ -96,23 +102,29 @@ export default async function MoviePage( datePublished: movie.releaseDate ?? undefined, dateModified: new Date().toISOString(), duration: movie.runtime ? toISO8601Duration(movie.runtime) : undefined, - director: movie.directors - ?.map(director => ({ - '@type': 'Person', - name: director.name ?? undefined, - image: director.profilePath ? getTmdbImage({ path: director.profilePath, size: 'w500' }) : undefined, - })), - aggregateRating: movie.voteAverage ? { - '@type': 'AggregateRating', - ratingValue: movie.voteAverage, - ratingCount: movie.voteCount ?? 0, - bestRating: 10, - worstRating: 1, - } : undefined, + director: movie.directors?.map((director) => ({ + '@type': 'Person', + name: director.name ?? undefined, + image: director.profilePath + ? getTmdbImage({ path: director.profilePath, size: 'w500' }) + : undefined, + })), + aggregateRating: movie.voteAverage + ? { + '@type': 'AggregateRating', + ratingValue: movie.voteAverage, + ratingCount: movie.voteCount ?? 0, + bestRating: 10, + worstRating: 1, + } + : undefined, }; return ( <> -