parent
eaad2d56f0
commit
fa28f68551
36 changed files with 962 additions and 368 deletions
77
src/components/app.tsx
Normal file
77
src/components/app.tsx
Normal file
|
@ -0,0 +1,77 @@
|
|||
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;
|
42
src/components/appCategory.tsx
Normal file
42
src/components/appCategory.tsx
Normal file
|
@ -0,0 +1,42 @@
|
|||
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;
|
42
src/components/appList.tsx
Normal file
42
src/components/appList.tsx
Normal file
|
@ -0,0 +1,42 @@
|
|||
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;
|
|
@ -69,10 +69,15 @@ export interface IAppCategoryProps {
|
|||
}
|
||||
|
||||
export interface IAppListProps {
|
||||
apps?: Array<IAppProps>;
|
||||
categories?: Array<IAppCategoryProps>;
|
||||
apps?: Array<IAppProps>;
|
||||
}
|
||||
|
||||
export const defaults: IAppListProps = {
|
||||
categories: [],
|
||||
apps: [],
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a single app shortcut
|
||||
* @param {IAppProps} props the props of the given app
|
||||
|
@ -130,7 +135,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>
|
||||
|
@ -150,8 +155,9 @@ export const AppList = ({ categories, apps }: IAppListProps) => {
|
|||
)}
|
||||
</ListContainer>
|
||||
);
|
||||
|
||||
return <></>;
|
||||
} else {
|
||||
return <></>;
|
||||
}
|
||||
};
|
||||
|
||||
export default AppList;
|
||||
|
|
|
@ -37,7 +37,7 @@ export interface IBookmarkGroupProps {
|
|||
}
|
||||
|
||||
export interface IBookmarkListProps {
|
||||
groups?: Array<IBookmarkGroupProps>;
|
||||
groups: Array<IBookmarkGroupProps>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -63,24 +63,15 @@ 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) => {
|
||||
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 <></>;
|
||||
};
|
||||
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>
|
||||
);
|
||||
|
||||
export default BookmarkList;
|
||||
|
|
|
@ -20,7 +20,7 @@ const DateText = styled.h3`
|
|||
`;
|
||||
|
||||
export interface IGreeterComponentProps {
|
||||
greeter?: IGreeterProps;
|
||||
data: IGreeterProps;
|
||||
}
|
||||
|
||||
export interface IGreeterProps {
|
||||
|
@ -112,18 +112,13 @@ export const getDateString = (
|
|||
* @param {IGreeterComponentProps} data required greeter data
|
||||
* @returns {React.ReactNode} the greeter
|
||||
*/
|
||||
const Greeter = ({ greeter }: IGreeterComponentProps) => {
|
||||
if (greeter)
|
||||
return (
|
||||
<GreeterContainer>
|
||||
<DateText>
|
||||
{getDateString(greeter.days, greeter.months, greeter.dateformat)}
|
||||
</DateText>
|
||||
<GreetText>{getGreeting(greeter.greetings)}</GreetText>
|
||||
</GreeterContainer>
|
||||
);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
const Greeter = ({ data }: IGreeterComponentProps) => (
|
||||
<GreeterContainer>
|
||||
<DateText>
|
||||
{getDateString(data.days, data.months, data.dateformat)}
|
||||
</DateText>
|
||||
<GreetText>{getGreeting(data.greetings)}</GreetText>
|
||||
</GreeterContainer>
|
||||
);
|
||||
|
||||
export default Greeter;
|
||||
|
|
|
@ -31,12 +31,16 @@ const ItemContainer = styled.div`
|
|||
`;
|
||||
|
||||
export interface IImprintProps {
|
||||
fields: Array<IImprintFieldProps>;
|
||||
name: IImprintFieldProps;
|
||||
address: IImprintFieldProps;
|
||||
phone: IImprintFieldProps;
|
||||
email: IImprintFieldProps;
|
||||
url: IImprintFieldProps;
|
||||
text: string;
|
||||
}
|
||||
|
||||
export interface IImprintComponentProps {
|
||||
imprint?: IImprintProps;
|
||||
imprint: IImprintProps;
|
||||
}
|
||||
|
||||
interface IImprintFieldComponentProps {
|
||||
|
@ -68,49 +72,41 @@ export const onClose = () => {
|
|||
* @param {IImprintProps} props contents of the imprint
|
||||
* @returns {React.ReactNode} the imprint node
|
||||
*/
|
||||
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 <></>;
|
||||
};
|
||||
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>
|
||||
</>
|
||||
);
|
||||
|
||||
export default Imprint;
|
||||
|
|
|
@ -48,7 +48,7 @@ export interface ISearchProps {
|
|||
}
|
||||
|
||||
interface ISearchBarProps {
|
||||
search?: ISearchProps;
|
||||
search: ISearchProps;
|
||||
}
|
||||
|
||||
export const handleQueryWithProvider = (
|
||||
|
@ -79,13 +79,7 @@ export const handleQueryWithProvider = (
|
|||
* Renders a search bar
|
||||
* @param {ISearchBarProps} search - The search providers for the search bar to use
|
||||
*/
|
||||
const SearchBar = ({
|
||||
search = {
|
||||
placeholder: "",
|
||||
defaultProvider: "",
|
||||
providers: [],
|
||||
},
|
||||
}: ISearchBarProps) => {
|
||||
const SearchBar = ({ search }: ISearchBarProps) => {
|
||||
let [input, setInput] = useState<string>("");
|
||||
let [buttonsHidden, setButtonsHidden] = useState<boolean>(true);
|
||||
|
||||
|
|
|
@ -54,6 +54,11 @@ 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;
|
||||
|
@ -61,7 +66,6 @@ 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;
|
||||
|
@ -72,8 +76,8 @@ const ThemeSelect = styled(Select)`
|
|||
`;
|
||||
|
||||
interface ISettingsProps {
|
||||
themes?: Array<IThemeProps>;
|
||||
search?: ISearchProps;
|
||||
themes: Array<IThemeProps> | undefined;
|
||||
search: ISearchProps | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -95,36 +99,20 @@ const Settings = ({ themes, search }: ISettingsProps) => {
|
|||
<Section>
|
||||
<SectionHeadline>Theme:</SectionHeadline>
|
||||
<FormContainer>
|
||||
<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>
|
||||
<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>
|
||||
</FormContainer>
|
||||
<Button
|
||||
data-testid="button-submit"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue