mirror of
https://github.com/pawelmalak/flame.git
synced 2025-07-19 19:49:37 +02:00
Apps grid
This commit is contained in:
parent
7199e296b8
commit
0502a653ac
12 changed files with 171 additions and 13 deletions
|
@ -24,6 +24,8 @@
|
||||||
work correctly both with client-side routing and a non-root public URL.
|
work correctly both with client-side routing and a non-root public URL.
|
||||||
Learn how to configure a non-root public URL by running `npm run build`.
|
Learn how to configure a non-root public URL by running `npm run build`.
|
||||||
-->
|
-->
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Roboto:400,500,700,900" rel="stylesheet">
|
||||||
<title>React App</title>
|
<title>React App</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -21,7 +21,7 @@ const App = (): JSX.Element => {
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path='/' component={Home} />
|
<Route exact path='/' component={Home} />
|
||||||
<Route exact path='/settings' component={Settings} />
|
<Route path='/settings' component={Settings} />
|
||||||
</Switch>
|
</Switch>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
</Provider>
|
</Provider>
|
||||||
|
|
34
client/src/components/Apps/AppCard/AppCard.module.css
Normal file
34
client/src/components/Apps/AppCard/AppCard.module.css
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
.AppCard {
|
||||||
|
width: 100%;
|
||||||
|
/* height: 50px; */
|
||||||
|
/* max-width: 150px; */
|
||||||
|
/* border: 1px solid red; */
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AppCardIcon {
|
||||||
|
width: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AppCardDetails {
|
||||||
|
text-transform: uppercase;
|
||||||
|
/* display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.AppCardDetails h5 {
|
||||||
|
font-size: 1em;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--color-primary);
|
||||||
|
margin-bottom: -8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.AppCardDetails a {
|
||||||
|
color: var(--color-accent);
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 0.8em;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
18
client/src/components/Apps/AppCard/AppCard.tsx
Normal file
18
client/src/components/Apps/AppCard/AppCard.tsx
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import classes from './AppCard.module.css';
|
||||||
|
import Icon from '../../UI/Icon/Icon';
|
||||||
|
|
||||||
|
const AppCard = (): JSX.Element => {
|
||||||
|
return (
|
||||||
|
<div className={classes.AppCard}>
|
||||||
|
<div className={classes.AppCardIcon}>
|
||||||
|
<Icon icon='mdiBookOpenBlankVariant' />
|
||||||
|
</div>
|
||||||
|
<div className={classes.AppCardDetails}>
|
||||||
|
<h5>plex</h5>
|
||||||
|
<a href="/">plex.example.com</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AppCard;
|
|
@ -0,0 +1,28 @@
|
||||||
|
.Apps {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(1, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 430px) {
|
||||||
|
.Apps {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 670px) {
|
||||||
|
.Apps {
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 900px) {
|
||||||
|
.Apps {
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 320px — 480px: Mobile devices.
|
||||||
|
481px — 768px: iPads, Tablets.
|
||||||
|
769px — 1024px: Small screens, laptops.
|
||||||
|
1025px — 1200px: Desktops, large screens.
|
||||||
|
1201px and more — Extra large screens, TV. */
|
|
@ -1,16 +1,31 @@
|
||||||
import { Link } from 'react-router-dom';
|
import { Fragment } from 'react';
|
||||||
|
|
||||||
import classes from './Apps.module.css';
|
import classes from './Apps.module.css';
|
||||||
|
|
||||||
import { Container } from '../UI/Layout/Layout';
|
import { Container } from '../UI/Layout/Layout';
|
||||||
import Headline from '../UI/Headline/Headline';
|
import Headline from '../UI/Headlines/Headline/Headline';
|
||||||
|
import AppCard from './AppCard/AppCard';
|
||||||
|
|
||||||
const Apps = (): JSX.Element => {
|
const Apps = (): JSX.Element => {
|
||||||
return (
|
return (
|
||||||
<Container>
|
<div className={classes.Apps}>
|
||||||
<Headline title='Welcome' />
|
<AppCard />
|
||||||
<Link to='/settings'>settings</Link>
|
<AppCard />
|
||||||
</Container>
|
<AppCard />
|
||||||
|
<AppCard />
|
||||||
|
<AppCard />
|
||||||
|
<AppCard />
|
||||||
|
<AppCard />
|
||||||
|
<AppCard />
|
||||||
|
<AppCard />
|
||||||
|
<AppCard />
|
||||||
|
<AppCard />
|
||||||
|
<AppCard />
|
||||||
|
<AppCard />
|
||||||
|
<AppCard />
|
||||||
|
<AppCard />
|
||||||
|
<AppCard />
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
.HeadlineTitle {
|
.HeadlineTitle {
|
||||||
color: var(--color-primary);
|
color: var(--color-primary);
|
||||||
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
.HeadlineSubtitle {
|
.HeadlineSubtitle {
|
||||||
color: var(--color-primary);
|
color: var(--color-primary);
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-weight: 400;
|
||||||
}
|
}
|
|
@ -3,13 +3,13 @@ import classes from './Headline.module.css';
|
||||||
|
|
||||||
interface ComponentProps {
|
interface ComponentProps {
|
||||||
title: string;
|
title: string;
|
||||||
subtitle?: string;
|
subtitle?: string | JSX.Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Headline = (props: ComponentProps): JSX.Element => {
|
const Headline = (props: ComponentProps): JSX.Element => {
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<h2 className={classes.HeadlineTitle}>{props.title}</h2>
|
<h1 className={classes.HeadlineTitle}>{props.title}</h1>
|
||||||
{props.subtitle && <p className={classes.HeadlineSubtitle}>{props.subtitle}</p>}
|
{props.subtitle && <p className={classes.HeadlineSubtitle}>{props.subtitle}</p>}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)
|
)
|
|
@ -0,0 +1,7 @@
|
||||||
|
.SectionHeadline {
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--color-primary);
|
||||||
|
font-weight: 900;
|
||||||
|
font-size: 20px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
import classes from './SectionHeadline.module.css';
|
||||||
|
|
||||||
|
interface ComponentProps {
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SectionHeadline = (props: ComponentProps): JSX.Element => {
|
||||||
|
return (
|
||||||
|
<h2 className={classes.SectionHeadline}>{props.title}</h2>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SectionHeadline;
|
|
@ -1,4 +1,22 @@
|
||||||
.Container {
|
.Container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: var(--space-p-x);
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 320px — 480px: Mobile devices.
|
||||||
|
481px — 768px: iPads, Tablets.
|
||||||
|
769px — 1024px: Small screens, laptops.
|
||||||
|
1025px — 1200px: Desktops, large screens.
|
||||||
|
1201px and more — Extra large screens, TV. */
|
||||||
|
|
||||||
|
@media (min-width: 769px) {
|
||||||
|
.Container {
|
||||||
|
padding: 25px 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1201px) {
|
||||||
|
.Container {
|
||||||
|
padding: 50px 250px;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -2,6 +2,8 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
transition: all 0.3s;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
@ -9,8 +11,26 @@ body {
|
||||||
--color-primary: #EFF1FC;
|
--color-primary: #EFF1FC;
|
||||||
--color-accent: #6677EB;
|
--color-accent: #6677EB;
|
||||||
|
|
||||||
--space-p-x: 16px;
|
|
||||||
|
|
||||||
background-color: var(--color-background);
|
background-color: var(--color-background);
|
||||||
|
/* font weights
|
||||||
|
light 300
|
||||||
|
regular 400
|
||||||
|
semi-bold 600
|
||||||
|
bold 700
|
||||||
|
extra-bold 800
|
||||||
|
*/
|
||||||
font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, Roboto, sans-serif;
|
font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, Roboto, sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--color-primary);
|
||||||
|
text-decoration: none;
|
||||||
|
opacity: 0.75;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 320px — 480px: Mobile devices.
|
||||||
|
481px — 768px: iPads, Tablets.
|
||||||
|
769px — 1024px: Small screens, laptops.
|
||||||
|
1025px — 1200px: Desktops, large screens.
|
||||||
|
1201px and more — Extra large screens, TV. */
|
Loading…
Add table
Add a link
Reference in a new issue