Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

impr(web): ai assistant feature flag #426

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 33 additions & 8 deletions apps/web/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,44 @@ DUB_WORKSPACE_ID=XXXXXXXX
# Supabase
DATABASE_URL="postgres://postgres.xxx:[email protected]:6543/postgres?pgbouncer=true&connection_limit=10&connect_timeout=300"
DIRECT_URL="postgres://postgres.xxx:[email protected]:5432/postgres?pgbouncer=true&connection_limit=10&connect_timeout=300"
ISSUER_KEY=xxxx
ISSUER_ADDRESS=xxx
NEXT_PUBLIC_SUPABASE_URL="https://xxxx.supabase.co"
NEXT_PUBLIC_SUPABASE_ANON_KEY="xxxx.xxxx"
SUPABASE_SERVICE_ROLE_KEY="xxxx.xxxx"

# Email
RESEND_API_KEY="re_xxxxx"
RESEND_AUDIENCE_ID="xxxxxxxxx"
RECAPTCHA_SECRET_KEY="xxxxxxxx"

# overrides env.local
NEXT_PUBLIC_APP_ENV=prod
# Recaptcha
NEXT_PUBLIC_RECAPTCHA_SITE_KEY="xxxxxxxx"
NEXT_PUBLIC_RECAPTCHA_SECRET_KEY="xxxxxxxx"

# CMS
NEXT_PUBLIC_CMS_API_KEY="xxx"
NEXT_PUBLIC_CMS_GRAPHQL_API=https://graphql.datocms.com
CLAUDE_API_KEY=""
ALCHEMY_NOTIFY_TOKEN=xxxx
OPENAI_API_KEY=xxxx

# Environment
NEXT_PUBLIC_APP_ENV=prod

# Features
NEXT_PUBLIC_ENABLE_WALLET_REDIRECT="true"
NEXT_PUBLIC_FEAT_PRESALE="true"
NEXT_PUBLIC_FEAT_AI_ASSISTANT="true"

# API Keys
MULTIBASE_API_KEY="xxxxxxxx"
NEXT_PUBLIC_MULTIBASE_API_KEY="xxxxxxxx"
TRIGGER_SECRET_KEY="xxxxxxxx"
ALCHEMY_NOTIFY_TOKEN="xxxxxxxx"
OPENAI_API_KEY="xxxxxxxx"
HUGGINGFACE_API_KEY="xxxxxxxx"
YOUTUBE_API_KEY="xxxxxxxx"

# Verification Tokens
GOOGLE_SITE_VERIFICATION_TOKEN="xxxxxxxx"
PINTEREST_DOMAIN_VERIFICATION_TOKEN="xxxxxxxx"
NEXT_PUBLIC_GOOGLE_SITE_VERIFICATION_TOKEN="xxxxxxxx"
NEXT_PUBLIC_PINTEREST_DOMAIN_VERIFICATION_TOKEN="xxxxxxxx"

# App URL
NEXT_PUBLIC_APP_URL="dev.example.com"
20 changes: 8 additions & 12 deletions apps/web/app/(routes)/[lang]/[project]/auction/sitemap.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,23 @@
import { getDictionary } from '@/dictionaries'
import { AVAILABLE_LANGS } from '@/lib/config'
import { getProjects } from '@/lib/projects'
import type { ProjectPageProps } from '@/types/routing.type'
import type { MetadataRoute } from 'next'
import { generateStaticParams } from '../page'

export default async function sitemap({
params,
}: ProjectPageProps): Promise<MetadataRoute.Sitemap> {
const dict = await getDictionary(params.lang)
const projects = await getProjects(dict)
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const projects = await generateStaticParams()

return projects.map((project) => ({
url: `https://${process.env.NEXT_PUBLIC_APP_URL}/${project.slug}/auction`,
return projects.map((item) => ({
url: `https://${process.env.NEXT_PUBLIC_APP_URL}/${item.project}/auction`,
lastModified: new Date(),
changeFrequency: 'yearly',
priority: 0.9,
alternates: {
// ? e.g.: { 'en': 'https://example.com/en/...', 'es': 'https://example.com/es/...', ... }
languages: Object.fromEntries(
AVAILABLE_LANGS.map((lang) => [
lang,
`https://${process.env.NEXT_PUBLIC_APP_URL}/${lang}/${project.slug}/presale`,
`https://${process.env.NEXT_PUBLIC_APP_URL}/${lang}/${item.project}/auction`,
]),
),
},
}))
}
}
10 changes: 10 additions & 0 deletions apps/web/app/(routes)/[lang]/[project]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,13 @@ const DynamicCtaButton = dynamic(
loading: () => <Button variant="accent">Get Whitelisted</Button>,
},
)


export async function generateMetadata({ params }: ProjectPageProps) {
const dict = await getDictionary(params.lang)
const project = await getProjectBySlug(params.project, dict)
return {
title: project?.title,
description: project?.pitch,
}
}
7 changes: 7 additions & 0 deletions apps/web/app/(routes)/[lang]/[project]/presale/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,10 @@ export default async function ProjectPage({ params }: ProjectPageProps) {
</div>
)
}

export async function generateMetadata({ params }: ProjectPageProps) {
return {
title: `Presale - ${params.project}`,
description: `Participate in the presale for ${params.project}. Contribute and be a part of the project before it launches.`,
}
}
15 changes: 7 additions & 8 deletions apps/web/app/(routes)/[lang]/[project]/presale/sitemap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,22 @@ import { AVAILABLE_LANGS } from '@/lib/config'
import { getProjects } from '@/lib/projects'
import type { ProjectPageProps } from '@/types/routing.type'
import type { MetadataRoute } from 'next'
import { generateStaticParams } from '../page'

export default async function sitemap({
params,
}: ProjectPageProps): Promise<MetadataRoute.Sitemap> {
const dict = await getDictionary(params.lang)
const projects = await getProjects(dict)
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const projects = await generateStaticParams()

return projects.map((project) => ({
url: `https://${process.env.NEXT_PUBLIC_APP_URL}/${project.slug}/presale`,
return projects.map((item) => ({
url: `https://${process.env.NEXT_PUBLIC_APP_URL}/${item.project}/presale`,
lastModified: new Date(),
changeFrequency: 'yearly',
priority: 0.9,
alternates: {
// ? e.g.: { 'en': 'https://example.com/en/...', 'es': 'https://example.com/es/...', ... }
languages: Object.fromEntries(
AVAILABLE_LANGS.map((lang) => [
lang,
`https://${process.env.NEXT_PUBLIC_APP_URL}/${lang}/${project.slug}/presale`,
`https://${process.env.NEXT_PUBLIC_APP_URL}/${lang}/${item.project}/presale`,
]),
),
},
Expand Down
20 changes: 8 additions & 12 deletions apps/web/app/(routes)/[lang]/[project]/sitemap.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
import { getDictionary } from '@/dictionaries'
import { AVAILABLE_LANGS } from '@/lib/config'
import { getProjects } from '@/lib/projects'
import type { ProjectPageProps } from '@/types/routing.type'
import type { MetadataRoute } from 'next'
import { generateStaticParams } from './page'

export default async function sitemap({
params,
}: ProjectPageProps): Promise<MetadataRoute.Sitemap> {
const dict = await getDictionary(params.lang)
const projects = await getProjects(dict)
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const projects = await generateStaticParams()

return projects.map((project) => ({
url: `https://${process.env.NEXT_PUBLIC_APP_URL}/${project.slug}`,
return projects.map((item) => ({
url: `https://${process.env.NEXT_PUBLIC_APP_URL}/${item.project}`,
lastModified: new Date(),
priority: 0.9,
changeFrequency: 'yearly',
priority: 0.7,
alternates: {
// ? e.g.: { 'en': 'https://example.com/en/...', 'es': 'https://example.com/es/...', ... }
languages: Object.fromEntries(
AVAILABLE_LANGS.map((lang) => [
lang,
`https://${process.env.NEXT_PUBLIC_APP_URL}/${lang}/${project.slug}`,
`https://${process.env.NEXT_PUBLIC_APP_URL}/${lang}/${item.project}`,
]),
),
},
Expand Down
4 changes: 2 additions & 2 deletions apps/web/app/(routes)/[lang]/about/about-bitlauncher/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const content: AboutBitlauncherPageContent = {
}

export const metadata: Metadata = {
title: 'Bitlauncher',
title: 'About Bitlauncher - AI & Cryptocurrency Launchpad',
description:
'Be part of the intelligent future and join the Ai/Web3 revolution now!',
'Discover Bitlauncher, the pioneering launchpad dedicated to transforming AI and cryptocurrency. Join the AI/Web3 revolution today!',
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import { AVAILABLE_LANGS } from '@/lib/config'
import type { CommonPageProps } from '@/types/routing.type'
import type { MetadataRoute } from 'next'

export default async function sitemap({
params,
}: CommonPageProps): Promise<MetadataRoute.Sitemap> {
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
return [
{
url: `https://${process.env.NEXT_PUBLIC_APP_URL}/about/about-bitlauncher`,
Expand Down
50 changes: 20 additions & 30 deletions apps/web/app/(routes)/[lang]/blog/[category]/[slug]/sitemap.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,24 @@
import { AVAILABLE_LANGS } from '@/lib/config'
import { getBlogCategoryLandingData } from '@/services/datocms'
import { getAllArticles } from '@/services/datocms/datocms-all-articles.service'
import type { MetadataRoute } from 'next'
import type { ArticlePageProps } from './page'

export default async function sitemap(
props: ArticlePageProps,
): Promise<MetadataRoute.Sitemap> {
const {
params: { lang, category },
} = props
const data = await getBlogCategoryLandingData(lang, category)
if (!data) return []

const { sections } = data
if (!sections) return []

const slugs = sections.map((section) => section.slug)

return slugs.map((slug) => ({
url: `https://${process.env.NEXT_PUBLIC_APP_URL}/${lang}/blog/${category}/${slug}`,
lastModified: new Date(),
priority: 0.5,
alternates: {
// ? e.g.: { 'en': 'https://example.com/en/...', 'es': 'https://example.com/es/...', ... }
languages: Object.fromEntries(
AVAILABLE_LANGS.map((lang) => [
lang,
`https://${process.env.NEXT_PUBLIC_APP_URL}/${lang}/blog/${category}/${slug}`,
]),
),
},
}))
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const articles = await getAllArticles()
if (!articles) return []

return articles.flatMap((item) =>
item.articles.map((article) => ({
url: `https://${process.env.NEXT_PUBLIC_APP_URL}/blog/${item.category}/${article.slug}`,
lastModified: article._publishedAt,
priority: 0.6,
alternates: {
languages: Object.fromEntries(
AVAILABLE_LANGS.map((lang) => [
lang,
`https://${process.env.NEXT_PUBLIC_APP_URL}/${lang}/blog/${item.category}/${article.slug}`,
]),
),
},
})),
)
}
24 changes: 7 additions & 17 deletions apps/web/app/(routes)/[lang]/blog/[category]/sitemap.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
import { AVAILABLE_LANGS } from '@/lib/config'
import { getArticleSections } from '@/services/datocms'
import { getAllArticles } from '@/services/datocms/datocms-all-articles.service'
import type { MetadataRoute } from 'next'
import type { CategoryPageProps } from './page'

export default async function sitemap(
props: CategoryPageProps,
): Promise<MetadataRoute.Sitemap> {
const {
params: { lang },
} = props
let sections = []
try {
sections = await getArticleSections(lang)
} catch (error) {
return []
}
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const articles = await getAllArticles()
if (!articles) return []

const categories = sections.map((section) => section.slug)
return categories.map((category) => ({
url: `https://${process.env.NEXT_PUBLIC_APP_URL}/${lang}/blog/${category}`,
const categoryUrls = [...new Set(articles.map((article) => article.category))]
return categoryUrls.map((category) => ({
url: `https://${process.env.NEXT_PUBLIC_APP_URL}/blog/${category}`,
lastModified: new Date(),
priority: 0.7,
alternates: {
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/(routes)/[lang]/blog/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default async function BlogPage({ params }: BlogPageProps) {
export async function generateMetadata({
params,
}: BlogPageProps): Promise<Metadata> {
const pageSeo = await getPageSeoText('home')
const pageSeo = await getPageSeoText('bitlauncher')
const seoData = {
title: pageSeo.pageSeo?.title || '',
description: pageSeo.pageSeo?.description || '',
Expand Down
5 changes: 1 addition & 4 deletions apps/web/app/(routes)/[lang]/blog/sitemap.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import { AVAILABLE_LANGS } from '@/lib/config'
import type { CommonPageProps } from '@/types/routing.type'
import type { MetadataRoute } from 'next'

export default async function sitemap({
params,
}: CommonPageProps): Promise<MetadataRoute.Sitemap> {
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
return [
{
url: `https://${process.env.NEXT_PUBLIC_APP_URL}/blog`,
Expand Down
4 changes: 2 additions & 2 deletions apps/web/app/(routes)/[lang]/learn/security/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default async function SecurityTips({ params }: CommonPageProps) {
}

export const metadata: Metadata = {
title: 'Security Tips | Bitlauncher',
title: 'Top Security Tips for a Safer Digital Experience',
description:
'Be part of the intelligent future and join the Ai/Web3 revolution now!',
'Discover essential security tips to protect yourself online. Join the AI/Web3 revolution and stay ahead with our expert advice.',
}
2 changes: 1 addition & 1 deletion apps/web/app/(routes)/[lang]/legal/privacy/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default async function PrivacyPolicy({ params }: CommonPageProps) {
}

export const metadata: Metadata = {
title: 'Privacy Policy | Bitlauncher',
title: 'Privacy Policy',
description:
'Read our Privacy Policy to understand how we protect and manage your data in our crypto launchpad application.',
}
6 changes: 3 additions & 3 deletions apps/web/app/(routes)/[lang]/legal/terms/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default async function PrivacyPolicy({ params }: CommonPageProps) {
}

export const metadata: Metadata = {
title: 'Privacy Policy | Bitlauncher',
title: 'Terms of Service',
description:
'Read our Privacy Policy to understand how we protect and manage your data in our crypto launchpad application.',
}
'Review our Terms of Service to understand the rules and regulations for using our crypto launchpad application.',
}
Loading