generated from idea2app/Next-Bootstrap-ts
-
Notifications
You must be signed in to change notification settings - Fork 8
Closed
Labels
Description
Task description
在保留现有数据内容的前提下,让界面更酷炫。要修改的组件:
Open-Source-Bazaar.github.io/pages/hackathon/[id].tsx
Lines 82 to 287 in babc91a
| 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
Task source
https://open-source-bazaar.feishu.cn/record/LzFmrMyMVe5s2BcCKo7csS4Unyf
Reactions are currently unavailable