Finished replacing components

Closes #17, #15
This commit is contained in:
Neshura 2022-12-16 00:11:30 +01:00
parent f15b98d09a
commit 2ec2f70772
No known key found for this signature in database
GPG key ID: ACDF5B6EBECF6B0A
9 changed files with 103 additions and 168 deletions

View file

@ -1,6 +1,8 @@
import Link from 'next/link' import Link from 'next/link';
import styled, { DefaultTheme } from 'styled-components' import Image from 'next/image';
import styled, { DefaultTheme } from 'styled-components';
import { CustomLink } from '../../interfaces/LinkTypes'; import { CustomLink } from '../../interfaces/LinkTypes';
import { Service } from '../../interfaces/Services';
// needed for Online Status checks // needed for Online Status checks
// TODO: migrate to shared Status type for Games and Services // TODO: migrate to shared Status type for Games and Services
@ -53,7 +55,7 @@ export const PageCard = styled.div`
p { p {
margin: 0; margin: 0;
font-size: 1.25rem; font-size: 1.2rem;
line-height: 1.5; line-height: 1.5;
} }
@ -63,6 +65,7 @@ export const PageCard = styled.div`
} }
` `
// replaces the three status classes
const OnlineStatus = styled.p<OnlinePropType>` const OnlineStatus = styled.p<OnlinePropType>`
color: ${props => { color: ${props => {
let ret; let ret;
@ -83,11 +86,54 @@ const OnlineStatus = styled.p<OnlinePropType>`
}}; }};
` `
// replaces .cardwarn
const CardContentWarning = styled.p`
color: ${({ theme }) => theme.colors.secondary};
`
// replaces .contentIcon
const CardContentTitleIcon = styled.div`
object-fit: "contain";
margin-right: 0.4rem;
position: relative;
aspect-ratio: 1;
height: 1.5rem;
`
// replaces .contentTitle
const CardContentTitleWrap = styled.div`
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
margin-bottom: 1rem;
h2 {
margin: 0;
white-space: nowrap;
}
`
const CardContentTitle = ({ content }: { content: Service | CustomLink }) => {
return (
<CardContentTitleWrap>
{
content.icon ? (
<CardContentTitleIcon>
<Image alt="icon" src={content.icon} fill></Image>
</CardContentTitleIcon>
) : (<></>)
}
<h2>{content.name}</h2>
</CardContentTitleWrap>
)
}
// Card Content Component for Games Page // Card Content Component for Games Page
export const PageCardContentGame = ({ content }: { content: CustomLink }) => { export const CardContentGame = ({ content }: { content: CustomLink }) => {
return ( return (
<> <>
<h2>{content.name}</h2> <CardContentTitle content={content} />
<p>{content.desc}</p> <p>{content.desc}</p>
<p>{content.ip}</p> <p>{content.ip}</p>
<OnlineStatus status={content.status}>{content.status}</OnlineStatus> <OnlineStatus status={content.status}>{content.status}</OnlineStatus>
@ -96,3 +142,13 @@ export const PageCardContentGame = ({ content }: { content: CustomLink }) => {
} }
// Card Content Component for Services Page // Card Content Component for Services Page
export const CardContentService = ({ content }: { content: Service }) => {
return (
<>
<CardContentTitle content={content} />
<OnlineStatus status={content.status}>{content.status}</OnlineStatus>
<p>{content.desc}</p>
<CardContentWarning>{content.warn}</CardContentWarning>
</>
)
}

View file

@ -1,5 +1,11 @@
import styled from 'styled-components' import styled from 'styled-components'
export const StyledBody = styled.body`
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
`
export const Page = styled.div` export const Page = styled.div`
width: 100%; width: 100%;

View file

@ -1,11 +1,9 @@
// Probably a good idea to spread this out into multiple files under a folder once it gets bigger // Probably a good idea to spread this out into multiple files under a folder once it gets bigger
import { createGlobalStyle, DefaultTheme } from 'styled-components' import { createGlobalStyle, DefaultTheme } from 'styled-components'
// TODO: unsure whether needed export const GlobalStyle = createGlobalStyle`
/* const GlobalStyle = createGlobalStyle`
html, html,
body { body {
color: ${({ theme }) => theme.colors.primary};
padding: 0; padding: 0;
margin: 0; margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
@ -21,8 +19,6 @@ import { createGlobalStyle, DefaultTheme } from 'styled-components'
} }
` `
export default GlobalStyle; */
export const lightTheme: DefaultTheme = { export const lightTheme: DefaultTheme = {
themeName: "Light Theme", themeName: "Light Theme",
themeId: 0, themeId: 0,

View file

@ -1,11 +1,11 @@
import '/styles/globals.css' import '/styles/globals.css'
import type { ReactElement, ReactNode } from 'react' import { Fragment, ReactElement, ReactNode } from 'react'
import Layout from '../components/layout' import Layout from '../components/layout'
import type { NextPage } from 'next' import type { NextPage } from 'next'
import { AppProps } from 'next/app'; import { AppProps } from 'next/app';
import { DefaultTheme, ThemeProvider } from 'styled-components'; import { DefaultTheme, ThemeProvider } from 'styled-components';
import { createContext, useContext, useEffect, useState } from 'react' import { createContext, useContext, useEffect, useState } from 'react'
import { darkTheme } from '../components/themes'; import { darkTheme, GlobalStyle } from '../components/themes';
import { getTheme } from '../components/themeselector'; import { getTheme } from '../components/themeselector';
export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & { export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
@ -44,10 +44,14 @@ export default function Website({ Component, pageProps }: AppPropsWithLayout) {
<Layout>{page}</Layout>)) <Layout>{page}</Layout>))
return ( return (
<ThemeProvider theme={selectedTheme}> <Fragment>
<GlobalStyle />
<ThemeProvider theme={selectedTheme}>
<ThemeUpdateContext.Provider value={setselectedTheme}> <ThemeUpdateContext.Provider value={setselectedTheme}>
{getLayout(<Component {...pageProps} />)} {getLayout(<Component {...pageProps} />)}
</ThemeUpdateContext.Provider> </ThemeUpdateContext.Provider>
</ThemeProvider> </ThemeProvider>
</Fragment>
) )
} }

View file

@ -1,14 +1,15 @@
import { Html, Head, Main, NextScript, DocumentContext } from 'next/document' import { Html, Head, Main, NextScript } from 'next/document'
import { StyledBody } from '../components/styles/generic'
export default function Document() { export default function Document() {
return ( return (
<Html lang='en'> <Html lang='en'>
<Head /> <Head />
<body> <StyledBody>
<Main /> <Main />
<NextScript /> <NextScript />
</body> </StyledBody>
</Html> </Html>
) )
} }

View file

@ -1,9 +1,8 @@
import Head from 'next/head' import Head from 'next/head'
import styles from '/styles/Home.module.css'
import fsPromises from 'fs/promises' import fsPromises from 'fs/promises'
import path from 'path' import path from 'path'
import type { CustomLink, EntryList } from '../interfaces/LinkTypes' import type { CustomLink, EntryList } from '../interfaces/LinkTypes'
import { PageContentBox, PageCard, PageDescription, PageTitle, PageCardContentGame } from '../components/styles/content' import { PageContentBox, PageCard, PageDescription, PageTitle, CardContentGame } from '../components/styles/content'
import Link from 'next/link' import Link from 'next/link'
function Servers(props: EntryList) { function Servers(props: EntryList) {
@ -30,7 +29,7 @@ function Servers(props: EntryList) {
return ( return (
<PageCard key={item.name}> <PageCard key={item.name}>
<Link href={item.href}> <Link href={item.href}>
<PageCardContentGame content={item} /> <CardContentGame content={item} />
</Link> </Link>
</PageCard> </PageCard>
) )
@ -38,7 +37,7 @@ function Servers(props: EntryList) {
else { else {
return ( return (
<PageCard key={item.name}> <PageCard key={item.name}>
<PageCardContentGame content={item} /> <CardContentGame content={item} />
</PageCard> </PageCard>
) )
} }

View file

@ -1,11 +1,10 @@
import Head from 'next/head' import Head from 'next/head'
import Link from 'next/link' import Link from 'next/link'
import styles from '/styles/Home.module.css'
import { Service, ServiceStatus, ServiceType, ServiceLocation } from '../interfaces/Services'; import { Service, ServiceStatus, ServiceType, ServiceLocation } from '../interfaces/Services';
import Dockerode from 'dockerode'; import Dockerode from 'dockerode';
import { ReactElement } from 'react' import { ReactElement } from 'react'
import useSWR from 'swr'; import useSWR from 'swr';
import Image from 'next/image'; import { PageCard, CardContentService, PageContentBox, PageDescription, PageTitle } from '../components/styles/content';
const fetcher = (url: string) => fetch(url).then((res) => res.json()) const fetcher = (url: string) => fetch(url).then((res) => res.json())
@ -18,51 +17,28 @@ function Services() {
else if (loadingInitial) { content = <div>Loading</div> } else if (loadingInitial) { content = <div>Loading</div> }
else if (loadingFull) { else if (loadingFull) {
content = content =
<div className={styles.grid}> <PageContentBox>
{initialData?.map((item: Service) => ( {initialData?.map((item: Service) => (
<Link className={styles.contentcard} key={item.name} href={item.href}> <PageCard key={item.name}>
<div className={styles.contentTitle}> <Link key={item.name} href={item.href}>
{ <CardContentService content={item} />
item.icon ? ( </Link>
<div className={styles.contentIcon}> </PageCard>
<Image alt="icon" src={item.icon} layout="fill" objectFit="contain"></Image>
</div>
) : (<></>)
}
<h2>{item.name}</h2>
</div>
<div className={item.status === ServiceStatus.online ? styles.statusOnline : item.status === ServiceStatus.offline ? styles.statusOffline : styles.statusLoading}>
{item.status}
</div>
<div><p>{item.desc}</p></div>
<div className={styles.cardwarn}><p>{item.warn}</p></div>
</Link>
))} ))}
</div> </PageContentBox>
} }
else if (fullData) { else if (fullData) {
content = content =
<div className={styles.grid}> <PageContentBox>
{fullData.map((item: Service) => ( {fullData.map((item: Service) => (
<Link className={styles.contentcard} key={item.name} href={item.href}> <PageCard key={item.name}>
<div className={styles.contentTitle}> <Link key={item.name} href={item.href}>
{ <CardContentService content={item} />
item.icon ? ( </Link>
<div className={styles.contentIcon}> </PageCard>
<Image alt="icon" src={item.icon} fill></Image>
</div>
) : (<></>)
}
<h2>{item.name}</h2>
</div>
<div className={item.status === ServiceStatus.online ? styles.statusOnline : item.status === ServiceStatus.offline ? styles.statusOffline : styles.statusLoading}>
{item.status}
</div>
<div><p>{item.desc}</p></div>
<div className={styles.cardwarn}><p>{item.warn}</p></div>
</Link>
))} ))}
</div> </PageContentBox>
} }
else { else {
content = <div>Error loading data</div> content = <div>Error loading data</div>
@ -77,13 +53,13 @@ function Services() {
<meta name="description" content="Lists all available Services, most likely up-to-date" /> <meta name="description" content="Lists all available Services, most likely up-to-date" />
</Head> </Head>
<h1 className={styles.title}> <PageTitle>
Service List Service List
</h1> </PageTitle>
<p className={styles.description}> <PageDescription>
Lists all available Services, most likely up-to-date Lists all available Services, most likely up-to-date
</p> </PageDescription>
{content} {content}
</> </>

View file

@ -1,78 +1 @@
.container {
padding: 0 2rem;
}
.title a {
color: var(--def-orange);
text-decoration: none;
}
.title a:hover,
.title a:focus,
.title a:active {
text-decoration: underline;
}
.code {
background: var(--black-1e);
border-radius: 5px;
padding: 0.75rem;
font-size: 1.1rem;
font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
Bitstream Vera Sans Mono, Courier New, monospace;
}
.contentcardstatic {
margin: 1rem;
padding: 1rem;
text-align: center;
color: inherit;
text-decoration: none;
border: 1px solid var(--black-2d);
border-radius: 10px;
border-color: var(--def-blue);
transition: color 0.15s ease, border-color 0.15s ease;
max-width: 300px;
}
.contentcard:hover,
.contentcard:focus,
.contentcard:active {
color: var(--def-orange);
border-color: var(--def-orange);
}
.contentTitle {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
.contentTitle h2 {
white-space: nowrap;
}
.contentIcon {
object-fit: "contain";
margin-right: 0.4rem;
position: relative;
aspect-ratio: 1;
height: 1.5rem;
}
.cardwarn {
color: var(--def-orange);
}
.logo {
height: 1em;
margin-left: 0.5rem;
}
@media (max-width: 600px) {
.grid {
width: 100%;
flex-direction: column;
}
}

View file

@ -1,27 +1 @@
html,
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}
:root {
--black-0f: #0f0f0f;
--black-1e: #1e1e1e;
--black-2d: #2d2d2d;
--def-blue: #00aaff;
--def-orange: #ff5300;
--def-red: #ff0000;
--def-green: #00ff00;
}
a {
color: inherit;
text-decoration: none;
}
* {
box-sizing: border-box;
}