This commit is contained in:
phntxx 2021-07-14 01:18:28 +02:00
parent ca2f7a763d
commit eaad2d56f0
36 changed files with 366 additions and 960 deletions

View file

@ -1,77 +0,0 @@
import Icon from "./icon";
import styled from "styled-components";
const AppContainer = styled.a`
display: flex;
flex: 1 0 auto;
padding: 1rem;
color: ${(props) => props.theme.mainColor};
font-weight: 500;
text-transform: uppercase;
margin: 0;
text-decoration: none;
font-size: 1rem;
`;
const IconContainer = styled.div`
display: flex;
justify-content: center;
align-items: center;
margin-right: 0.5rem;
`;
const DetailsContainer = styled.div`
display: flex;
flex-direction: column;
`;
const AppName = styled.div`
a:hover {
text-decoration: underline;
}
`;
const AppDescription = styled.p`
text-transform: uppercase;
margin: 0;
font-size: 0.65rem;
font-weight: 400;
color: ${(props) => props.theme.accentColor};
`;
export interface IAppProps {
name: string;
icon: string;
url: string;
displayURL: string;
newTab?: boolean;
}
/**
* Renders a single app shortcut
* @param {IAppProps} props the props of the given app
* @returns {React.ReactNode} the child node for the given app
*/
const App = ({ name, icon, url, displayURL, newTab }: IAppProps) => {
const linkAttrs =
newTab !== undefined && newTab
? {
target: "_blank",
rel: "noopener noreferrer",
}
: {};
return (
<AppContainer href={url} {...linkAttrs}>
<IconContainer>
<Icon name={icon} />
</IconContainer>
<DetailsContainer>
<AppName>{name}</AppName>
<AppDescription>{displayURL}</AppDescription>
</DetailsContainer>
</AppContainer>
);
};
export default App;

View file

@ -1,42 +0,0 @@
import styled from "styled-components";
import App, { IAppProps } from "./app";
import { ItemList, Item, SubHeadline } from "./elements";
const CategoryHeadline = styled(SubHeadline)`
padding-top: 1rem;
`;
const CategoryContainer = styled.div`
width: 100%;
`;
export interface IAppCategoryProps {
name: string;
items: Array<IAppProps>;
}
/**
* Renders one app category
* @param {IAppCategoryProps} props props of the given category
* @returns {React.ReactNode} the app category node
*/
const AppCategory = ({ name, items }: IAppCategoryProps) => (
<CategoryContainer>
{name && <CategoryHeadline>{name}</CategoryHeadline>}
<ItemList>
{items.map(({ name, icon, displayURL, newTab, url }, index) => (
<Item key={[name, index].join("")}>
<App
name={name}
icon={icon}
url={url}
displayURL={displayURL}
newTab={newTab}
/>
</Item>
))}
</ItemList>
</CategoryContainer>
);
export default AppCategory;

View file

@ -1,42 +0,0 @@
import AppCategory, { IAppCategoryProps } from "./appCategory";
import { IAppProps } from "./app";
import { Headline, ListContainer } from "./elements";
export interface IAppListProps {
categories?: Array<IAppCategoryProps>;
apps?: Array<IAppProps>;
}
/**
* Renders one list containing all app categories and uncategorized apps
* @param {IAppListProps} props props of the given list of apps
* @returns {React.ReactNode} the app list component
*/
const AppList = ({ categories, apps }: IAppListProps) => {
if (apps || categories) {
return (
<ListContainer>
<Headline>Applications</Headline>
{categories &&
categories.map(({ name, items }, index) => (
<AppCategory
key={[name, index].join("")}
name={name}
items={items}
/>
))}
{apps && (
<AppCategory
name={categories ? "Uncategorized apps" : ""}
items={apps}
/>
)}
</ListContainer>
);
} else {
return <></>;
}
};
export default AppList;

View file

@ -69,15 +69,10 @@ export interface IAppCategoryProps {
}
export interface IAppListProps {
categories?: Array<IAppCategoryProps>;
apps?: Array<IAppProps>;
categories?: Array<IAppCategoryProps>;
}
export const defaults: IAppListProps = {
categories: [],
apps: [],
};
/**
* Renders a single app shortcut
* @param {IAppProps} props the props of the given app
@ -135,7 +130,7 @@ export const AppCategory = ({ name, items }: IAppCategoryProps) => (
* @returns {React.ReactNode} the app list component
*/
export const AppList = ({ categories, apps }: IAppListProps) => {
if (apps || categories) {
if (apps || categories)
return (
<ListContainer>
<Headline>Applications</Headline>
@ -155,9 +150,8 @@ export const AppList = ({ categories, apps }: IAppListProps) => {
)}
</ListContainer>
);
} else {
return <></>;
}
return <></>;
};
export default AppList;

View file

@ -37,7 +37,7 @@ export interface IBookmarkGroupProps {
}
export interface IBookmarkListProps {
groups: Array<IBookmarkGroupProps>;
groups?: Array<IBookmarkGroupProps>;
}
/**
@ -63,15 +63,24 @@ export const BookmarkGroup = ({ name, items }: IBookmarkGroupProps) => (
* @param {IBookmarkListProps} props props of the given bookmark list
* @returns {React.ReactNode} the bookmark list component
*/
const BookmarkList = ({ groups }: IBookmarkListProps) => (
<ListContainer>
<Headline>Bookmarks</Headline>
<ItemList>
{groups.map(({ name, items }, index) => (
<BookmarkGroup key={[name, index].join("")} name={name} items={items} />
))}
</ItemList>
</ListContainer>
);
const BookmarkList = ({ groups }: IBookmarkListProps) => {
if (groups)
return (
<ListContainer>
<Headline>Bookmarks</Headline>
<ItemList>
{groups.map(({ name, items }, index) => (
<BookmarkGroup
key={[name, index].join("")}
name={name}
items={items}
/>
))}
</ItemList>
</ListContainer>
);
return <></>;
};
export default BookmarkList;

View file

@ -20,7 +20,7 @@ const DateText = styled.h3`
`;
export interface IGreeterComponentProps {
data: IGreeterProps;
greeter?: IGreeterProps;
}
export interface IGreeterProps {
@ -112,13 +112,18 @@ export const getDateString = (
* @param {IGreeterComponentProps} data required greeter data
* @returns {React.ReactNode} the greeter
*/
const Greeter = ({ data }: IGreeterComponentProps) => (
<GreeterContainer>
<DateText>
{getDateString(data.days, data.months, data.dateformat)}
</DateText>
<GreetText>{getGreeting(data.greetings)}</GreetText>
</GreeterContainer>
);
const Greeter = ({ greeter }: IGreeterComponentProps) => {
if (greeter)
return (
<GreeterContainer>
<DateText>
{getDateString(greeter.days, greeter.months, greeter.dateformat)}
</DateText>
<GreetText>{getGreeting(greeter.greetings)}</GreetText>
</GreeterContainer>
);
return <></>;
};
export default Greeter;

View file

@ -31,16 +31,12 @@ const ItemContainer = styled.div`
`;
export interface IImprintProps {
name: IImprintFieldProps;
address: IImprintFieldProps;
phone: IImprintFieldProps;
email: IImprintFieldProps;
url: IImprintFieldProps;
fields: Array<IImprintFieldProps>;
text: string;
}
export interface IImprintComponentProps {
imprint: IImprintProps;
imprint?: IImprintProps;
}
interface IImprintFieldComponentProps {
@ -72,41 +68,49 @@ export const onClose = () => {
* @param {IImprintProps} props contents of the imprint
* @returns {React.ReactNode} the imprint node
*/
const Imprint = ({ imprint }: IImprintComponentProps) => (
<>
<ListContainer>
<Headline>About</Headline>
<ItemList>
<ItemContainer>
<SubHeadline>Imprint</SubHeadline>
<Modal
element="text"
text="View Imprint"
title="Legal Disclosure"
condition={!window.location.href.endsWith("#imprint")}
onClose={onClose}
>
<div>
<ModalSubHeadline>
Information in accordance with section 5 TMG
</ModalSubHeadline>
<>
{imprint.name && <ImprintField field={imprint.name} />}
{imprint.address && <ImprintField field={imprint.address} />}
{imprint.email && <ImprintField field={imprint.email} />}
{imprint.phone && <ImprintField field={imprint.phone} />}
{imprint.url && <ImprintField field={imprint.url} />}
</>
</div>
<div>
<ModalSubHeadline>Imprint</ModalSubHeadline>
{imprint.text && <Text>{imprint.text}</Text>}
</div>
</Modal>
</ItemContainer>
</ItemList>
</ListContainer>
</>
);
const Imprint = ({ imprint }: IImprintComponentProps) => {
if (imprint)
return (
<>
<ListContainer>
<Headline>About</Headline>
<ItemList>
<ItemContainer>
<SubHeadline>Imprint</SubHeadline>
<Modal
element="text"
text="View Imprint"
title="Legal Disclosure"
condition={!window.location.href.endsWith("#imprint")}
onClose={onClose}
>
{imprint.fields && (
<div>
<ModalSubHeadline>
Information in accordance with section 5 TMG
</ModalSubHeadline>
<>
{imprint.fields.map((field, index) => (
<ImprintField
key={[field.text, index].join("")}
field={field}
/>
))}
</>
</div>
)}
<div>
<ModalSubHeadline>Imprint</ModalSubHeadline>
{imprint.text && <Text>{imprint.text}</Text>}
</div>
</Modal>
</ItemContainer>
</ItemList>
</ListContainer>
</>
);
return <></>;
};
export default Imprint;

View file

@ -48,7 +48,7 @@ export interface ISearchProps {
}
interface ISearchBarProps {
search: ISearchProps;
search?: ISearchProps;
}
export const handleQueryWithProvider = (
@ -79,7 +79,13 @@ export const handleQueryWithProvider = (
* Renders a search bar
* @param {ISearchBarProps} search - The search providers for the search bar to use
*/
const SearchBar = ({ search }: ISearchBarProps) => {
const SearchBar = ({
search = {
placeholder: "",
defaultProvider: "",
providers: [],
},
}: ISearchBarProps) => {
let [input, setInput] = useState<string>("");
let [buttonsHidden, setButtonsHidden] = useState<boolean>(true);

View file

@ -54,11 +54,6 @@ const Code = styled.p`
color: ${(props) => props.theme.accentColor};
`;
const ThemeHeader = styled.p`
grid-column: 1 / 4;
color: ${(props) => props.theme.accentColor};
`;
const ThemeSelect = styled(Select)`
-webkit-appearance: button;
-moz-appearance: button;
@ -66,6 +61,7 @@ const ThemeSelect = styled(Select)`
text-transform: uppercase;
font-family: Roboto, sans-serif;
font-weight: 400;
border-radius: 0;
border: 1px solid ${(props) => props.theme.mainColor};
color: ${(props) => props.theme.mainColor};
background: none;
@ -76,8 +72,8 @@ const ThemeSelect = styled(Select)`
`;
interface ISettingsProps {
themes: Array<IThemeProps> | undefined;
search: ISearchProps | undefined;
themes?: Array<IThemeProps>;
search?: ISearchProps;
}
/**
@ -99,20 +95,36 @@ const Settings = ({ themes, search }: ISettingsProps) => {
<Section>
<SectionHeadline>Theme:</SectionHeadline>
<FormContainer>
<ThemeHeader>Light</ThemeHeader>
<ThemeSelect
items={themes}
onChange={(theme: IThemeProps) => setNewLightTheme(theme)}
current={currentLightTheme}
testId="light"
></ThemeSelect>
<ThemeHeader>Dark</ThemeHeader>
<ThemeSelect
items={themes}
onChange={(theme: IThemeProps) => setNewDarkTheme(theme)}
current={currentDarkTheme}
testId="dark"
></ThemeSelect>
<Table>
<tbody>
<TableRow>
<HeadCell>Light</HeadCell>
<HeadCell>Dark</HeadCell>
</TableRow>
<TableRow>
<TableCell>
<ThemeSelect
items={themes}
onChange={(theme: IThemeProps) =>
setNewLightTheme(theme)
}
current={currentLightTheme}
testId="light"
></ThemeSelect>
</TableCell>
<TableCell>
<ThemeSelect
items={themes}
onChange={(theme: IThemeProps) =>
setNewDarkTheme(theme)
}
current={currentDarkTheme}
testId="dark"
></ThemeSelect>
</TableCell>
</TableRow>
</tbody>
</Table>
</FormContainer>
<Button
data-testid="button-submit"