Skip to content

Commit

Permalink
Merge pull request #904 from AlexLin625/Alexlin625-feat-news-template
Browse files Browse the repository at this point in the history
feat(omi-template): 添加新闻/杂志模板
  • Loading branch information
dntzhang authored Jul 15, 2024
2 parents 5571322 + df37a97 commit 33c55af
Show file tree
Hide file tree
Showing 5 changed files with 372 additions and 0 deletions.
117 changes: 117 additions & 0 deletions packages/omi-templates/src/pages/news/example.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { BriefNewsList_t } from './home'
import { NewsHeaderComponent } from './news-header'
import '@/components/omiu/button'

export interface NewsContent_t {
title: string
author: string
date: string
content: string
}

export interface AuthorCardConfig_t {
name: string
avatar: string
introduction: string
}

function renderNewsContent(content: NewsContent_t) {
return (
<div class="flex flex-col gap-4">
<div class="text-4xl font-bold py-4">{content.title}</div>
<div class="flex flex-row gap-4">
<div class="text-zinc-600 dark:text-primary-foreground">{content.author}</div>
<div class="text-zinc-600 dark:text-primary-foreground">{content.date}</div>
</div>

<div class="text-zinc-800 dark:text-zinc-400 py-6">{content.content}</div>
</div>
)
}

function shareCard() {
return (
<div class="flex flex-row gap-4 shadow rounded bg-card text-card-foreground dark:border p-6 items-center justify-center my-8">
<o-button theme="success">分享到微信</o-button>
<o-button theme="primary">分享到微信</o-button>
<o-button theme="default">收藏</o-button>
</div>
)
}

function recommendationCard(config: BriefNewsList_t) {
return (
<div class="flex flex-col gap-4 shadow rounded bg-card text-card-foreground dark:border p-6 my-8">
<div class="text-2xl font-bold text-zinc-700 dark:text-foreground py-4">推荐阅读</div>
<div class="flex flex-col gap-2">
{config.news.map((news) => {
return (
<a class="text-zinc-600 dark:text-zinc-400 hover:text-primary" href={news.url}>
{news.title}
</a>
)
})}
</div>
</div>
)
}

function authorCard(config: AuthorCardConfig_t) {
return (
<div class="flex flex-col gap-4 shadow rounded bg-card text-card-foreground dark:border p-6 items-center my-8">
<img src={config.avatar} alt="avatar" class="w-24 h-24 rounded-full shadow-lg object-cover" />
<div class="text-2xl text-zinc-700 dark:text-foreground py-4 text-center">{config.name}</div>
<div class="text-zinc-600 dark:text-zinc-400 text-sm">{config.introduction}</div>
</div>
)
}

const newsContent: NewsContent_t = {
title: '内容示例页',
author: '艾丽卡·斯通',
date: '2021-10-01',
content:
'**这里应当接入平台内容数据库,或者通过接口/HTML渲染器等获取内容。** 流由就往流刃乙十蝶急申占打知瓜娘給而王。力物房隻肉員錯邊很急路扒把,羊校玩助秋兌巴胡兌几南躲意從乾條南,畫是新荷字年園金,片吉牠自古寺跟。早對方安昌山長水土石合向即乞後牛泉平,福要央出想姐弓蛋想夕?給爬找放常哥快送刀買幾品良室金辛,有古心八免林見害片寫,林以是冒日:讀口刀且北聽?草支草何蝶找鳥唱綠。門正言童肖飯隻結物習,主村真。公實才何冬信麻笑害隻喝她害媽從燈波貝,尺以鴨說着苗刀清們位條春、書過還想喝白道讀起像長故者甲,牙就已幫拉流牛具波田晚住小米戶兔亮飯雲,封法昌物,裝息良,尤頭幸。頁的枝兌視看見飛;法士這找還室只二停百服休姐,朵今錯神、目苦定回示嗎要兆過院田片這朱「葉魚」頭雄百百。巾弓把半交校信拍河蝶民喝?草念波唱那。火月怎哪,又牛火的婆具幫合松干給說手里里字丟朵:屋六父吹牠面九師美英在汗語園由假「科昌多立青」免請共示奶歡「房清根次」。看左故月蛋路送、星向詞斗朱朋收方戊親清院在細即停申寺快,流上虎也地頭乍現記由光元貝百就亭羊春不,香辛你色同東跟泉遠科院雲。穴姊服打。麻很封刃帶?直東紅亭亭里大牠食員黑,怎水唱有寺以男耳立用助兔;菜兄福物天各旁米,象院造吹乙水意葉皮支蛋!扒午目平種助。',
}

const briefNews: BriefNewsList_t = {
news: [
{
title: '点击任意标题进入内容示例页',
isImportant: true,
url: '/#/news/example',
},
{
title: '企鹅操作系统重大更新,或称业界标杆',
url: '/#/news/example',
},
{
title: '量子计算机突破:谷歌宣布实现‘量子霸权+’',
isImportant: true,
url: '/#/news/example',
},
],
}

const authorConfig: AuthorCardConfig_t = {
name: '艾丽卡·斯通',
avatar: 'https://http.cat/404',
introduction:
'艾丽卡·斯通是一位资深科技记者和专栏作家,专注于报道人工智能、区块链和未来科技趋势。她拥有计算机科学学位,曾在多家知名科技公司担任顾问。艾丽卡的文章以其深度分析和前瞻性的视角受到读者的喜爱。',
}

export function Example() {
return (
<div class="w-full flex flex-col items-center">
<NewsHeaderComponent />
<div class="w-full flex flex-col items-center xl:flex-row xl:justify-center xl:items-start">
<div class="w-full max-w-xl flex flex-col px-8">
{renderNewsContent(newsContent)} {shareCard()}
</div>
<div class="w-full max-w-xl flex flex-col px-8 xl:ml-12">
{recommendationCard(briefNews)} {authorCard(authorConfig)}
</div>
</div>
</div>
)
}
182 changes: 182 additions & 0 deletions packages/omi-templates/src/pages/news/home.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import { NewsHeaderComponent } from './news-header'

interface NewsCardConfig_t {
title: string
img: string
isLong?: boolean
isLarge?: boolean
}

interface NewsCardListConfig_t {
cards: NewsCardConfig_t[]
}

export interface BriefNews_t {
isImportant?: boolean
title: string
url: string
}

export interface BriefNewsList_t {
news: BriefNews_t[]
}

/**
* 渲染一个新闻预览卡片
*/
function renderNewsPreviewCard(config: NewsCardConfig_t) {
let sizePrefix = 'w-48 h-32 '
if (config.isLong) sizePrefix = 'w-64 h-80 '
if (config.isLarge) sizePrefix = 'w-96 h-64 '

return (
<div
class={sizePrefix + 'relative shadow-md hover:shadow-lg duration-200 rounded-md overflow-hidden cursor-pointer'}
>
<img src={config.img} alt="news" class="absolute w-full h-full top-0 left-0 object-cover" />
<p class="text-white absolute bottom-0 text-center w-full py-2 bg-black bg-opacity-60 hover:text-primary px-3">
{config.title}
</p>
</div>
)
}

/**
* 渲染一条简要新闻
*/
function renderBriefNews(news: BriefNews_t) {
let classModifier = ''
if (news.isImportant) classModifier = ' font-bold'

return (
<a class={'py-2 hover:text-primary' + classModifier} href={news.url}>
{news.title}
</a>
)
}

function NewsCardList(config: NewsCardListConfig_t) {
return (
<div class="flex-row justify-center flex">
<div class="grid grid-cols-2 gap-[4px]">
{config.cards.map((card) => {
return renderNewsPreviewCard(card)
})}
</div>
</div>
)
}

function BriefNewsList(config: BriefNewsList_t) {
return (
<div class="flex flex-col">
<p class="text-2xl font-bold text-zinc-700 dark:text-foreground py-4">新闻速递</p>
{config.news.map((news) => {
return renderBriefNews(news)
})}
</div>
)
}

const cardListConfig: NewsCardListConfig_t = {
cards: [
{
title: '奥米区多地出现猫猫',
img: 'https://http.cat/101',
},
{
title: '如何看待猫猫的出现',
img: 'https://http.cat/200',
},
{
title: '奥米公司惊现猫失踪',
img: 'https://http.cat/404',
},
{
title: '非法访问,何去何从?',
img: 'https://http.cat/502',
},
{
title: '高并发请求的下一代方案',
img: 'https://http.cat/500',
},
],
}

const briefNews: BriefNewsList_t = {
news: [
{
title: '点击任意标题进入内容示例页',
isImportant: true,
url: '/#/news/example',
},
{
title: '企鹅操作系统重大更新,或称业界标杆',
url: '/#/news/example',
},
{
title: '量子计算机突破:谷歌宣布实现‘量子霸权+’',
isImportant: true,
url: '/#/news/example',
},
{
title: '火星网络接入测试成功,首个星际Wi-Fi热点即将开放',
url: '/#/news/example',
},
{
title: 'AI助手通过律师资格考试,成为首个人工智能法律执业者',
url: '/#/news/example',
},
{
title: '苹果秘密研发新操作系统,代号‘iFuture’,传将于2025年面世',
url: '/#/news/example',
},
{
title: '全球首个商用时光机亮相,时间旅行不再是科幻梦想',
isImportant: true,
url: '/#/news/example',
},
{
title: '特斯拉发布新款飞行汽车,预定已超百万',
url: '/#/news/example',
},
],
}

export function Home() {
return (
<div class="flex flex-col gap-2 pb-16">
<NewsHeaderComponent />
<div class="w-full flex flex-row justify-center px-8">
<div class="container flex flex-col items-center gap-8 xl:flex-row xl:items-start xl:justify-between">
<div class="flex flex-col gap-2">
<p class="text-2xl font-bold text-zinc-700 dark:text-foreground py-4">图看世界</p>
<div class="w-full flex flex-col items-center py-2">
{renderNewsPreviewCard({
title: '高并发请求的下一代方案',
img: 'https://http.cat/500',
isLarge: true,
})}
</div>
{NewsCardList(cardListConfig)}
</div>
<div class="flex flex-col gap-2">
{BriefNewsList(briefNews)}
{BriefNewsList(briefNews)}
</div>

<div class="flex flex-col gap-2">
{BriefNewsList(briefNews)}
<div class="w-full flex flex-col items-center py-2">
{renderNewsPreviewCard({
title: '特斯拉发布新款飞行汽车,预定已超百万',
img: 'https://http.cat/500',
isLong: true,
})}
</div>
</div>
</div>
</div>
</div>
)
}
66 changes: 66 additions & 0 deletions packages/omi-templates/src/pages/news/news-header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
interface NewsCategory_t {
name: string
topics: string[]
}

interface NewsHeaderConfig_t {
categories: NewsCategory_t[]
}

/**
* 渲染一个标题里的新闻分类块
*/
function renderNewsCategory(category: NewsCategory_t) {
return (
<div class="flex flex-row items-center h-32 px-4">
<div class="text-2xl font-bold p-8 dark:text-foreground">{category.name}</div>
<div class="grid grid-rows-2 grid-cols-3">
{category.topics.map((topic) => {
return (
<a
class="font-normal text-zinc-600 dark:text-zinc-400 px-2 py-1 hover:text-primary"
href="https://example.org"
>
{topic}
</a>
)
})}
</div>
</div>
)
}

function NewsHeader(config: NewsHeaderConfig_t) {
return (
<div class="flex flex-row w-full items-center justify-center border-b-2 border-solid border-zinc-200 dark:border-zinc-800 mb-8">
<div class="grid grid-cols-2 xl:grid-cols-4">
{config.categories.map((category) => {
return renderNewsCategory(category)
})}
</div>
</div>
)
}

const headerConfig: NewsHeaderConfig_t = {
categories: [
{
name: '国内',
topics: ['国内1', '国内2'],
},
{
name: '国际',
topics: ['国际1', '国际2', '国际3'],
},
{
name: '财经',
topics: ['财经1', '财经2', '财经3', '财经4', '财经5'],
},
{
name: '汽车',
topics: ['汽车1', '汽车2', '汽车3'],
},
],
}

export const NewsHeaderComponent = () => <NewsHeader {...headerConfig} />
2 changes: 2 additions & 0 deletions packages/omi-templates/src/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export const routes = [
createRoute('/blog', () => import('./pages/blog')),
createRoute('/product/:id', () => import('./pages/product')),
createRoute('/education', () => import('./pages/education')),
createRoute('/news', () => import('./pages/news/home')),
createRoute('/news/example', () => import('./pages/news/example')),

createRoute('/chat', () => import('./pages/chat')),
createRoute('/components', () => import('./pages/components')),
Expand Down
5 changes: 5 additions & 0 deletions packages/omi-templates/src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ export const navbarItems = signal<NavbarItem[]>([
path: '/education',
value: 'education',
},
{
text: '新闻杂志',
path: '/news',
value: 'news',
},
{
text: '组件',
path: '/components/button',
Expand Down

0 comments on commit 33c55af

Please sign in to comment.