mirror of
https://github.com/jellyfin/jellyfin.org.git
synced 2026-09-03 05:20:06 +03:00
Refactor client card to common component
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
import React from 'react';
|
||||
|
||||
import DetailsCard from './common/DetailsCard';
|
||||
import PlatformIcon from './PlatformIcon';
|
||||
import { Client, ClientType, LicenseType } from '../data/clients';
|
||||
|
||||
import './ClientDetails.css';
|
||||
|
||||
const ClientTypeBadge = ({ clientType }: { clientType: ClientType }) => {
|
||||
if (clientType === ClientType.Official) {
|
||||
return <span className='badge badge--primary margin-right--sm'>Official</span>;
|
||||
@@ -22,36 +21,29 @@ const LicenseTypeBadge = ({ licenseType }: { licenseType: LicenseType }) => {
|
||||
};
|
||||
|
||||
const ClientDetails = ({ client }: { client: Client }) => (
|
||||
<div className='card client margin-bottom--md'>
|
||||
<div className='card__header client__header'>
|
||||
<div className='client__header__start'>
|
||||
<h3>{client.name}</h3>
|
||||
<div className='client__header__start__badges'>
|
||||
<ClientTypeBadge clientType={client.clientType} />
|
||||
<LicenseTypeBadge licenseType={client.licenseType} />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{client.platforms.map((platform, index) => (
|
||||
<PlatformIcon key={`${platform}-${index}`} platform={platform} size={36} className='client__platform-icon' />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className='card__body padding-top--sm'>{client.description}</div>
|
||||
<div className='card__footer client__footer'>
|
||||
{client.secondaryLinks?.map(({ id, url, name }) => (
|
||||
<a key={id} href={url} className='button button--outline button--primary'>
|
||||
{name}
|
||||
</a>
|
||||
))}
|
||||
<div style={{ flexGrow: 1 }} />
|
||||
{client.primaryLinks.map(({ id, url, name }) => (
|
||||
<a key={id} href={url} className='button button--primary'>
|
||||
{name}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<DetailsCard
|
||||
title={client.name}
|
||||
description={client.description}
|
||||
badges={
|
||||
<>
|
||||
<ClientTypeBadge clientType={client.clientType} />
|
||||
<LicenseTypeBadge licenseType={client.licenseType} />
|
||||
</>
|
||||
}
|
||||
icons={client.platforms.map((platform, index) => (
|
||||
<PlatformIcon key={`${platform}-${index}`} platform={platform} size={36} className='client__platform-icon' />
|
||||
))}
|
||||
primaryButtons={client.primaryLinks.map(({ id, url, name }) => (
|
||||
<a key={id} href={url} className='button button--primary'>
|
||||
{name}
|
||||
</a>
|
||||
))}
|
||||
secondaryButtons={client.secondaryLinks?.map(({ id, url, name }) => (
|
||||
<a key={id} href={url} className='button button--outline button--primary'>
|
||||
{name}
|
||||
</a>
|
||||
))}
|
||||
/>
|
||||
);
|
||||
|
||||
export default ClientDetails;
|
||||
|
||||
@@ -1,80 +1,80 @@
|
||||
/* stylelint-disable docusaurus/copyright-header */
|
||||
|
||||
.client__header {
|
||||
.details-card__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.client__header__start {
|
||||
.details-card__header__start {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.client__header__start h3 {
|
||||
.details-card__header__start h3 {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.client__header__start__badges {
|
||||
.details-card__header__start__badges {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.client__footer {
|
||||
.details-card__footer {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.client__platform-icon {
|
||||
.details-card__icons > * {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.client__footer .button {
|
||||
.details-card__footer .button {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.client__footer .button:first-of-type {
|
||||
.details-card__footer .button:first-of-type {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 420px) {
|
||||
.client__header {
|
||||
.details-card__header {
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.client__platform-icon {
|
||||
.details-card__icons > * {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.client__platform-icon:first-of-type {
|
||||
.details-card__icons > *:first-of-type {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.card__body {
|
||||
.details-card .card__body {
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 560px) {
|
||||
.client__header__start {
|
||||
.details-card__header__start {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.client__header__start__badges {
|
||||
.details-card__header__start__badges {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.client__header__start__badges:first-of-type {
|
||||
.details-card__header__start__badges:first-of-type {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.client__footer {
|
||||
.details-card__footer {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.client__footer .button {
|
||||
.details-card__footer .button {
|
||||
margin: 1rem 0 0;
|
||||
}
|
||||
|
||||
.client__footer .button:first-of-type {
|
||||
.details-card__footer .button:first-of-type {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import React, { FunctionComponent, ReactNode } from 'react';
|
||||
|
||||
import './DetailsCard.css';
|
||||
|
||||
type DetailsCardProps = {
|
||||
title: string;
|
||||
description: string;
|
||||
badges?: ReactNode;
|
||||
icons?: ReactNode;
|
||||
primaryButtons?: Array<ReactNode>;
|
||||
secondaryButtons?: Array<ReactNode>;
|
||||
};
|
||||
|
||||
const DetailsCard: FunctionComponent<DetailsCardProps> = ({
|
||||
title,
|
||||
description,
|
||||
badges = [],
|
||||
icons = [],
|
||||
primaryButtons = [],
|
||||
secondaryButtons = []
|
||||
}) => (
|
||||
<div className='card details-card margin-bottom--md'>
|
||||
<div className='card__header details-card__header'>
|
||||
<div className='details-card__header__start'>
|
||||
<h3>{title}</h3>
|
||||
<div className='details-card__header__start__badges'>{badges}</div>
|
||||
</div>
|
||||
<div className='details-card__icons'>{icons}</div>
|
||||
</div>
|
||||
<div className='card__body padding-top--sm'>{description}</div>
|
||||
<div className='card__footer details-card__footer'>
|
||||
{secondaryButtons}
|
||||
<div style={{ flexGrow: 1 }} />
|
||||
{primaryButtons}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default DetailsCard;
|
||||
Reference in New Issue
Block a user