Skip to content

Commit

Permalink
Merge branch 'develop' into pedro/cow-425-uniswap-v2-withdraw-cow-review
Browse files Browse the repository at this point in the history
  • Loading branch information
yvesfracari committed Dec 11, 2024
2 parents 6d7bec3 + ed152f7 commit 2e229c6
Show file tree
Hide file tree
Showing 149 changed files with 7,533 additions and 7,595 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,4 @@ out

# Next.js sitemap
apps/cow-fi/public/robots.txt
apps/cow-fi/public/sitemap*
apps/cow-fi/public/sitemap*
4 changes: 2 additions & 2 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"apps/cowswap-frontend": "1.92.0",
"apps/cowswap-frontend": "1.92.2",
"apps/explorer": "2.38.0",
"libs/permit-utils": "0.5.0",
"libs/widget-lib": "0.18.0",
Expand All @@ -18,7 +18,7 @@
"libs/types": "1.5.0",
"libs/ui": "1.15.0",
"libs/wallet": "1.7.0",
"apps/cow-fi": "1.17.0",
"apps/cow-fi": "1.18.0",
"libs/wallet-provider": "1.0.0",
"libs/ui-utils": "1.1.0",
"libs/abis": "1.2.0",
Expand Down
2 changes: 1 addition & 1 deletion apps/cow-fi/.env
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ DUNE_API_KEY=tuBkOcda6ymMvmnpIX9Qer9Xb5hJ2rf8
NEXT_PUBLIC_GOOGLE_ANALYTICS=
NEXT_PUBLIC_AWS_API_ENDPOINT="https://bff.cow.fi/proxies/tokens"
NEXT_PUBLIC_LAUNCH_DARKLY_KEY=
NEXT_PUBLIC_SITE_URL="https://cow.fi"
NEXT_PUBLIC_SITE_URL="https://cow.fi"
7 changes: 7 additions & 0 deletions apps/cow-fi/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## [1.18.0](https://github.com/cowprotocol/cowswap/compare/cow-fi-v1.17.0...cow-fi-v1.18.0) (2024-12-09)


### Features

* **cow-fi:** cache data and pages ([#5169](https://github.com/cowprotocol/cowswap/issues/5169)) ([39c94cc](https://github.com/cowprotocol/cowswap/commit/39c94cca11db8a97d9add3ac05c1623755ecd2b3))

## [1.17.0](https://github.com/cowprotocol/cowswap/compare/cow-fi-v1.16.0...cow-fi-v1.17.0) (2024-12-04)


Expand Down
5 changes: 5 additions & 0 deletions apps/cow-fi/app/(learn)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Layout } from '@/components/Layout'

export default function LayoutPage({ children }: { children: React.ReactNode }) {
return <Layout>{children}</Layout>
}
101 changes: 101 additions & 0 deletions apps/cow-fi/app/(learn)/learn/[article]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
'use server'

import React from 'react'
import {
Article,
getAllArticleSlugs,
getArticleBySlug,
getArticles,
getCategories,
SharedRichTextComponent,
} from '../../../../services/cms'
import { ArticlePageComponent } from '@/components/ArticlePageComponent'
import { notFound } from 'next/navigation'
import type { Metadata } from 'next'
import { stripHtmlTags } from '@/util/stripHTMLTags'
import { getPageMetadata } from '@/util/getPageMetadata'

function isRichTextComponent(block: any): block is SharedRichTextComponent {
return block.body !== undefined
}

type Props = {
params: Promise<{ article: string }>
}

export async function generateMetadata({ params }: Props): Promise<Metadata> {
const articleSlug = (await params).article

if (!articleSlug) return {}

const article = await getArticleBySlug(articleSlug)
const attributes = article?.attributes
const { title, blocks, description, cover } = attributes || {}
const coverImageUrl = cover?.data?.attributes?.url

const content =
blocks?.map((block: SharedRichTextComponent) => (isRichTextComponent(block) ? block.body : '')).join(' ') || ''
const plainContent = stripHtmlTags(content)

return getPageMetadata({
absoluteTitle: `${title} - CoW DAO`,
description: description
? stripHtmlTags(description)
: plainContent.length > 150
? stripHtmlTags(plainContent.substring(0, 147)) + '...'
: stripHtmlTags(plainContent),
image: coverImageUrl,
})
}

export async function generateStaticParams() {
const slugs = await getAllArticleSlugs()

return slugs.map((article) => ({ article }))
}

export default async function ArticlePage({ params }: Props) {
const articleSlug = (await params).article
const article = await getArticleBySlug(articleSlug)

if (!article) {
return notFound()
}

const articlesResponse = await getArticles()
const articles = articlesResponse.data

// Fetch featured articles
const featuredArticlesResponse = await getArticles({
filters: {
featured: {
$eq: true,
},
},
pageSize: 7, // Limit to 7 articles
})
const featuredArticles = featuredArticlesResponse.data

const randomArticles = getRandomArticles(articles, 3)
const categoriesResponse = await getCategories()
const allCategories =
categoriesResponse?.map((category: any) => ({
name: category?.attributes?.name || '',
slug: category?.attributes?.slug || '',
})) || []

return (
<ArticlePageComponent
article={article}
articles={articles}
randomArticles={randomArticles}
featuredArticles={featuredArticles}
allCategories={allCategories}
/>
)
}

function getRandomArticles(articles: Article[], count: number): Article[] {
const shuffled = articles.sort(() => 0.5 - Math.random())
return shuffled.slice(0, count)
}
10 changes: 10 additions & 0 deletions apps/cow-fi/app/(learn)/learn/articles/[[...pageIndex]]/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Metadata } from 'next'

export const metadata: Metadata = {
title: 'All articles',
description: 'All knowledge base articles in the Cow DAO ecosystem',
}

export default function LayoutPage({ children }: { children: React.ReactNode }) {
return children
}
67 changes: 67 additions & 0 deletions apps/cow-fi/app/(learn)/learn/articles/[[...pageIndex]]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
'use server'

import { Article, getArticles, getCategories } from '../../../../../services/cms'
import { ArticlesPageComponents } from '@/components/ArticlesPageComponents'

const ITEMS_PER_PAGE = 24

type Props = {
params: Promise<{ pageIndex?: string }>
}

export type ArticlesResponse = {
data?: Article[]
meta?: {
pagination?: {
total?: number
}
}
}

export async function generateStaticParams() {
const articlesResponse = await getArticles({ page: 0, pageSize: ITEMS_PER_PAGE })
const totalArticles = articlesResponse.meta?.pagination?.total || 0
const totalPages = Math.ceil(totalArticles / ITEMS_PER_PAGE)

return Array.from({ length: totalPages }, (_, i) => ({ pageIndex: [(i + 1).toString()] }))
}

export default async function Page({ params }: Props) {
const pageParam = (await params)?.pageIndex
const page = pageParam && pageParam.length > 0 ? parseInt(pageParam[0], 10) : 1

const articlesResponse = (await getArticles({ page, pageSize: ITEMS_PER_PAGE })) as ArticlesResponse

const totalArticles = articlesResponse.meta?.pagination?.total || 0
const articles =
articlesResponse.data?.map((article: Article) => ({
...article,
id: article.id || 0,
attributes: {
...article.attributes,
title: article.attributes?.title ?? 'Untitled',
description: article.attributes?.description ?? '',
slug: article.attributes?.slug ?? 'no-slug',
featured: article.attributes?.featured ?? false,
publishDateVisible: article.attributes?.publishDateVisible ?? false,
cover: article.attributes?.cover ?? {},
blocks: article.attributes?.blocks ?? [],
},
})) || []

const categoriesResponse = await getCategories()
const allCategories =
categoriesResponse?.map((category: any) => ({
name: category?.attributes?.name || '',
slug: category?.attributes?.slug || '',
})) || []

return (
<ArticlesPageComponents
articles={articles}
totalArticles={totalArticles}
currentPage={page}
allCategories={allCategories}
/>
)
}
12 changes: 12 additions & 0 deletions apps/cow-fi/app/(learn)/learn/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Metadata } from 'next'

export const metadata: Metadata = {
title: {
default: 'Knowledge Base - CoW DAO',
template: '%s - CoW DAO',
},
}

export default function LayoutPage({ children }: { children: React.ReactNode }) {
return children
}
45 changes: 45 additions & 0 deletions apps/cow-fi/app/(learn)/learn/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
'use server'

import { getArticles, getCategories } from '../../../services/cms'

import { LearnPageComponent } from '@/components/LearnPageComponent'

export default async function Page() {
const categoriesResponse = await getCategories()
const articlesResponse = await getArticles()

const featuredArticlesResponse = await getArticles({
filters: { featured: { $eq: true } },
pageSize: 6,
})

const categories =
categoriesResponse?.map((category: any) => {
const imageUrl = category?.attributes?.image?.data?.attributes?.url || ''

return {
name: category?.attributes?.name || '',
slug: category?.attributes?.slug || '',
description: category?.attributes?.description || '',
bgColor: category?.attributes?.backgroundColor || '#fff',
textColor: category?.attributes?.textColor || '#000',
link: `/learn/topic/${category?.attributes?.slug}`,
iconColor: '#fff',
imageUrl,
}
}) || []

const featuredArticles = featuredArticlesResponse.data.map((article) => {
const attributes = article.attributes
return {
title: attributes?.title || 'No title',
description: attributes?.description || 'No description',
link: `/learn/${attributes?.slug || 'no-slug'}`,
cover: attributes?.cover?.data?.attributes?.url || '',
}
})

return (
<LearnPageComponent categories={categories} articles={articlesResponse.data} featuredArticles={featuredArticles} />
)
}
64 changes: 64 additions & 0 deletions apps/cow-fi/app/(learn)/learn/topic/[topicSlug]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
'use server'

import React from 'react'
import { getAllCategorySlugs, getArticles, getCategories, getCategoryBySlug } from '../../../../../services/cms'
import { TopicPageComponent } from '@/components/TopicPageComponent'
import { notFound } from 'next/navigation'
import type { Metadata } from 'next'

type Props = {
params: Promise<{ topicSlug: string }>
}

export async function generateMetadata({ params }: Props): Promise<Metadata> {
const topicSlug = (await params).topicSlug

if (!topicSlug) return {}

const category = await getCategoryBySlug(topicSlug)
const { name, description } = category?.attributes || {}

return {
title: name,
description,
}
}

export async function generateStaticParams() {
const categoriesResponse = await getAllCategorySlugs()

return categoriesResponse.map((topicSlug) => ({ topicSlug }))
}

export default async function TopicPage({ params }: Props) {
const slug = (await params).topicSlug

const category = await getCategoryBySlug(slug)

if (!category) {
return notFound()
}

const articlesResponse = await getArticles({
page: 0,
pageSize: 50,
filters: {
categories: {
slug: {
$eq: slug,
},
},
},
})

const articles = articlesResponse.data

const categoriesResponse = await getCategories()
const allCategories =
categoriesResponse?.map((category: any) => ({
name: category?.attributes?.name || '',
slug: category?.attributes?.slug || '',
})) || []

return <TopicPageComponent category={category} allCategories={allCategories} articles={articles} />
}
10 changes: 10 additions & 0 deletions apps/cow-fi/app/(learn)/learn/topics/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Metadata } from 'next'

export const metadata: Metadata = {
title: 'Topics',
description: 'All knowledge base topics',
}

export default function LayoutPage({ children }: { children: React.ReactNode }) {
return children
}
27 changes: 27 additions & 0 deletions apps/cow-fi/app/(learn)/learn/topics/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use server'

import { getArticles, getCategories } from '../../../../services/cms'
import { TopicsPageComponent } from '@/components/TopicsPageComponent'

export default async function Page() {
const categoriesResponse = await getCategories()
const articlesResponse = await getArticles()

const categories =
categoriesResponse?.map((category: any) => {
const imageUrl = category?.attributes?.image?.data?.attributes?.url || ''

return {
name: category?.attributes?.name || '',
slug: category?.attributes?.slug || '',
description: category?.attributes?.description || '',
bgColor: category?.attributes?.backgroundColor || '#fff',
textColor: category?.attributes?.textColor || '#000',
link: `/learn/topic/${category?.attributes?.slug}`,
iconColor: 'transparent',
imageUrl,
}
}) || []

return <TopicsPageComponent categories={categories} articles={articlesResponse.data} />
}
Loading

0 comments on commit 2e229c6

Please sign in to comment.