Added production support for themes

also some css improvements
This commit is contained in:
Bastian Meissner 2020-05-22 00:28:02 +02:00
parent a82bdc1620
commit c2d5a90df5
5 changed files with 75 additions and 23 deletions

View file

@ -4,7 +4,14 @@ import styled from 'styled-components';
import selectedTheme from './themeManager'; import selectedTheme from './themeManager';
import { Headline, ListContainer, ItemList, Item, RefreshButton, ErrorMessage } from './elements'; import {
Headline,
ListContainer,
ItemList,
Item,
RefreshButton,
ErrorMessage
} from './elements';
const IconContainer = styled.div` const IconContainer = styled.div`
margin-right: 0.5vh; margin-right: 0.5vh;
@ -41,14 +48,14 @@ const App = styled.div`
padding: 1rem; padding: 1rem;
`; `;
function handleResponse(response) { const handleResponse = response => {
if (response.ok) { if (response.ok) {
return response.json(); return response.json();
} }
throw new Error('Failed to load app data.'); throw new Error('Failed to load app data.');
} };
function useAppData() { const useAppData = () => {
const [appData, setAppData] = useState({ apps: [], error: false }); const [appData, setAppData] = useState({ apps: [], error: false });
const fetchAppData = useCallback(() => { const fetchAppData = useCallback(() => {
(process.env.NODE_ENV === 'production' (process.env.NODE_ENV === 'production'
@ -63,15 +70,11 @@ function useAppData() {
}); });
}, []); }, []);
useEffect(() => {
console.log(appData)
}, [appData]);
useEffect(() => { useEffect(() => {
fetchAppData(); fetchAppData();
}, [fetchAppData]); }, [fetchAppData]);
return { appData, fetchAppData }; return { appData, fetchAppData };
} };
const AppList = () => { const AppList = () => {
const { const {

View file

@ -2,7 +2,14 @@ import React, { useCallback, useEffect, useState } from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import selectedTheme from './themeManager'; import selectedTheme from './themeManager';
import { Headline, ListContainer, ItemList, Item, RefreshButton, ErrorMessage } from './elements'; import {
Headline,
ListContainer,
ItemList,
Item,
RefreshButton,
ErrorMessage
} from './elements';
const Group = styled.h4` const Group = styled.h4`
font-family: Roboto, sans-serif; font-family: Roboto, sans-serif;
@ -28,15 +35,18 @@ const Bookmark = styled.a`
font-size: 14px; font-size: 14px;
`; `;
function handleResponse(response) { const handleResponse = response => {
if (response.ok) { if (response.ok) {
return response.json(); return response.json();
} }
throw new Error('Failed to load app data.'); throw new Error('Failed to load app data.');
} };
const useBookmarkData = () => { const useBookmarkData = () => {
const [bookmarkData, setBookmarkData] = useState({ groups: [], error: false }); const [bookmarkData, setBookmarkData] = useState({
groups: [],
error: false
});
const fetchBookmarkData = useCallback(() => { const fetchBookmarkData = useCallback(() => {
(process.env.NODE_ENV === 'production' (process.env.NODE_ENV === 'production'
? fetch('/bookmarks.json').then(handleResponse) ? fetch('/bookmarks.json').then(handleResponse)
@ -54,7 +64,7 @@ const useBookmarkData = () => {
fetchBookmarkData(); fetchBookmarkData();
}, [fetchBookmarkData]); }, [fetchBookmarkData]);
return { bookmarkData, fetchBookmarkData }; return { bookmarkData, fetchBookmarkData };
} };
const BookmarkList = () => { const BookmarkList = () => {
const { const {
@ -63,7 +73,7 @@ const BookmarkList = () => {
} = useBookmarkData(); } = useBookmarkData();
return ( return (
<ListContainer> <ListContainer>
<Headline>Applications</Headline> <Headline>Bookmarks</Headline>
<RefreshButton onClick={fetchBookmarkData}>refresh</RefreshButton> <RefreshButton onClick={fetchBookmarkData}>refresh</RefreshButton>
<ItemList> <ItemList>
{error && <ErrorMessage>{error}</ErrorMessage>} {error && <ErrorMessage>{error}</ErrorMessage>}

View file

@ -28,7 +28,6 @@ export const ItemList = styled.ul`
`; `;
export const Item = styled.li` export const Item = styled.li`
max-height: 100px;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
list-style: none; list-style: none;

View file

@ -1,13 +1,12 @@
import React, { useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import Select from 'react-select'; import Select from 'react-select';
import searchData from './data/search.json'; import searchData from './data/search.json';
import themeData from './data/themes.json';
import selectedTheme, { setTheme } from './themeManager'; import selectedTheme, { setTheme } from './themeManager';
import { Button, IconButton } from './elements'; import { Button, IconButton, ErrorMessage } from './elements';
const Modal = styled.div` const Modal = styled.div`
position: absolute; position: absolute;
@ -103,10 +102,43 @@ const SelectorStyle = {
} }
}; };
const handleResponse = response => {
if (response.ok) {
return response.json();
}
throw new Error('Failed to load app data.');
};
const useThemeData = () => {
const [themeData, setThemeData] = useState({ themes: [], error: false });
const fetchThemeData = useCallback(() => {
(process.env.NODE_ENV === 'production'
? fetch('/themes.json').then(handleResponse)
: import('./data/themes.json')
)
.then(jsonResponse => {
setThemeData({ ...jsonResponse, error: false });
})
.catch(error => {
setThemeData({ themes: [], error: error.message });
});
}, []);
useEffect(() => {
fetchThemeData();
}, [fetchThemeData]);
return { themeData, fetchThemeData };
};
const SettingsModal = () => { const SettingsModal = () => {
const [modalHidden, setModalHidden] = useState(true); const [modalHidden, setModalHidden] = useState(true);
const [newTheme, setNewTheme] = useState(); const [newTheme, setNewTheme] = useState();
const {
themeData: { themes, error },
fetchThemeData
} = useThemeData();
return ( return (
<> <>
<IconButton <IconButton
@ -118,17 +150,19 @@ const SettingsModal = () => {
icon="close" icon="close"
onClick={() => setModalHidden(!modalHidden)} onClick={() => setModalHidden(!modalHidden)}
/> />
{error && <ErrorMessage>{error}</ErrorMessage>}
<SelectContainer> <SelectContainer>
<Headline>Theme:</Headline> <Headline>Theme:</Headline>
<FormContainer> <FormContainer>
<Select <Select
options={themeData.themes} options={themes}
defaultValue={selectedTheme} defaultValue={selectedTheme}
onChange={e => { onChange={e => {
setNewTheme(e); setNewTheme(e);
}} }}
styles={SelectorStyle} styles={SelectorStyle}
/> />
<Button onClick={fetchThemeData}>Refresh</Button>
<Button <Button
onClick={() => setTheme(JSON.stringify(newTheme))} onClick={() => setTheme(JSON.stringify(newTheme))}
> >

View file

@ -1,4 +1,10 @@
import themeData from './data/themes.json'; const defaultTheme = {
label: 'Classic',
value: 0,
mainColor: '#000000',
accentColor: '#1e272e',
backgroundColor: '#ffffff'
};
const setTheme = theme => { const setTheme = theme => {
localStorage.setItem('theme', theme); localStorage.setItem('theme', theme);
@ -10,7 +16,7 @@ const resetTheme = () => {
}; };
const getTheme = () => { const getTheme = () => {
let selectedTheme = themeData.themes[0]; let selectedTheme = defaultTheme;
if ( if (
localStorage.getItem('theme') && localStorage.getItem('theme') &&