Skip to content

重新设计并开发【开源黑客松】飞书版主页 #60

@TechQuery

Description

@TechQuery

Task description

在保留现有数据内容的前提下,让界面更酷炫。要修改的组件:

const HackathonDetail: FC<HackathonDetailProps> = observer(({ activity, hackathon }) => {
const { t } = useContext(I18nContext);
const { name, summary, location, startTime, endTime, databaseSchema } = activity,
{ people, organizations, agenda, prizes, templates, projects } = hackathon;
const { forms } = databaseSchema as BiTableSchema;
return (
<>
<PageHead title={name as string} />
{/* Hero Section */}
<section className={styles.hero}>
<Container>
<h1 className={`text-center ${styles.title}`}>{name as string}</h1>
<p className={`text-center ${styles.description}`}>{summary as string}</p>
<Row className="mt-4 justify-content-center">
<Col md={4}>
<Card className={styles.infoCard}>
<Card.Body>
<h5 className="text-white mb-2">📍 {t('event_location')}</h5>
<p className="text-white-50 mb-0">
{(location as TableCellLocation)?.full_address}
</p>
</Card.Body>
</Card>
</Col>
<Col md={4}>
<Card className={styles.infoCard}>
<Card.Body>
<h5 className="text-white mb-2">{t('event_duration')}</h5>
<p className="text-white-50 mb-0">
{formatDate(startTime as string)} - {formatDate(endTime as string)}
</p>
</Card.Body>
</Card>
</Col>
</Row>
<ButtonGroup className="d-flex mt-3">
{FormButtonBar.map((key, index) => {
const list = forms[key]?.filter(
// @ts-expect-error Upstream types bug
({ shared_limit }) => shared_limit === 'anyone_editable',
);
return !list?.[0] ? null : list.length < 2 ? (
<Button href={list[0].shared_url} target="_blank" rel="noreferrer">
{index + 1}. {list[0].name}
</Button>
) : (
<DropdownButton
as={ButtonGroup}
title={`${index + 1}. ${t('product_submission')}`}
id={`dropdown-${key}`}
>
{list.map(({ name, shared_url }) => (
<Dropdown.Item key={name} href={shared_url} target="_blank" rel="noreferrer">
{name}
</Dropdown.Item>
))}
</DropdownButton>
);
})}
</ButtonGroup>
</Container>
</section>
<Container className="my-5">
<section className={`${styles.section} ${styles.prizeSection}`}>
<h2 className={styles.sectionTitle}>🏆 {t('prizes')}</h2>
<div className="mt-4">
<UserRankView
title={t('prizes')}
rank={prizes.map(({ name, image, price }, index) => ({
id: `prize-${index}`,
name: name as string,
avatar: fileURLOf(image),
score: price as number,
}))}
/>
</div>
</section>
<section className={styles.section}>
<h2 className={styles.sectionTitle}>📅 {t('agenda')}</h2>
<ol className="list-unstyled mt-4">
{agenda.map(({ name, type, summary, startedAt, endedAt }) => (
<li
key={name as string}
className={`${styles.agendaItem} ${styles[type?.toString().toLowerCase() || 'break']}`}
>
<h5 className="text-white mb-2">{name as string}</h5>
<p className="text-white-50 small mb-2">{summary as string}</p>
<div className="d-flex justify-content-between align-items-center">
<Badge bg={text2color(type as string)} className="me-2">
{t(type as I18nKey)}
</Badge>
<div className="text-white-50 small">
{formatDate(startedAt as string)} - {formatDate(endedAt as string)}
</div>
</div>
</li>
))}
</ol>
</section>
{/* Mid-front: Organizations - Horizontal logo layout */}
<section className={styles.section}>
<h2 className={styles.sectionTitle}>🏢 {t('organizations')}</h2>
<nav className={styles.orgContainer}>
{organizations.map(({ name, link, logo }) => (
<a
key={name as string}
href={link as string}
target="_blank"
rel="noreferrer"
title={name as string}
>
<LarkImage src={logo} alt={name as string} className={styles.orgLogo} />
</a>
))}
</nav>
</section>
{/* Mid-back: Templates - Using GitCard, 3-4 per row */}
<section className={`${styles.section} ${styles.templateSection}`}>
<h2 className={styles.sectionTitle}>🛠️ {t('templates')}</h2>
<Row className="mt-4 g-3" md={2} lg={3} xl={4}>
{templates.map(({ name, languages, tags, sourceLink, summary, previewLink }) => (
<Col key={name as string}>
<GitCard
full_name={name as string}
html_url={sourceLink as string}
languages={languages as string[]}
topics={tags as string[]}
description={summary as string}
homepage={previewLink as string}
/>
</Col>
))}
</Row>
</section>
{/* Mid-back: Projects - Narrow cards, 3-4 per row */}
<section className={styles.section}>
<h2 className={styles.sectionTitle}>💡 {t('projects')}</h2>
<Row as="ul" className="list-unstyled mt-4 g-3" md={2} lg={3} xl={4}>
{projects.map(({ id, name, score, summary, createdBy, members }) => (
<Col as="li" key={name as string}>
<Card className={styles.projectCard} body>
<div className="d-flex justify-content-between align-items-start mb-3">
<h6 className="text-white flex-grow-1">
<Link
className="stretched-link"
href={`${ActivityModel.getLink(activity)}/team/${id}`}
>
{name as string}
</Link>
</h6>
<div className={styles.scoreCircle}>{score as number}</div>
</div>
<p className="text-white-50 small mb-3">{summary as string}</p>
<div className="text-white-50 small mb-2">
<strong>{t('created_by')}:</strong>{' '}
<a href={`mailto:${(createdBy as TableCellUser)?.email}`}>
{(createdBy as TableCellUser)?.name}
</a>
</div>
<div className="text-white-50 small">
<strong>{t('members')}:</strong> {(members as string[]).join(', ')}
</div>
</Card>
</Col>
))}
</Row>
</section>
{/* Footer: Participants - Circular avatars only */}
<section className={styles.section}>
<h2 className={styles.sectionTitle}>👥 {t('participants')}</h2>
<nav className={styles.participantCloud}>
{people.map(({ name, avatar, githubLink }) => (
<a
key={name as string}
className="text-center"
target="_blank"
rel="noreferrer"
href={githubLink as string}
>
<LarkImage
className={styles.avatar}
src={avatar}
alt={name as string}
title={name as string}
/>
</a>
))}
</nav>
</section>
</Container>
</>
);
});

Reward currency

TQT $

Reward amount

100

Reward payer

水歌 tech-query@fcc-cd.dev

Task source

https://open-source-bazaar.feishu.cn/record/LzFmrMyMVe5s2BcCKo7csS4Unyf

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions