diff --git a/client/public/favicon.ico b/client/public/favicon.ico index a11777c..6741eba 100644 Binary files a/client/public/favicon.ico and b/client/public/favicon.ico differ diff --git a/client/public/index.html b/client/public/index.html index 4b73f3a..2ede77f 100644 --- a/client/public/index.html +++ b/client/public/index.html @@ -10,36 +10,15 @@ content="Web site created using create-react-app" /> - - - React App + Flame +
- + diff --git a/client/public/logo192.png b/client/public/logo192.png deleted file mode 100644 index fc44b0a..0000000 Binary files a/client/public/logo192.png and /dev/null differ diff --git a/client/public/logo512.png b/client/public/logo512.png deleted file mode 100644 index a4e47a6..0000000 Binary files a/client/public/logo512.png and /dev/null differ diff --git a/client/public/manifest.json b/client/public/manifest.json deleted file mode 100644 index 080d6c7..0000000 --- a/client/public/manifest.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "short_name": "React App", - "name": "Create React App Sample", - "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - }, - { - "src": "logo192.png", - "type": "image/png", - "sizes": "192x192" - }, - { - "src": "logo512.png", - "type": "image/png", - "sizes": "512x512" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" -} diff --git a/client/src/App.tsx b/client/src/App.tsx index 2d7fef5..9875f16 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -18,6 +18,10 @@ if (localStorage.theme) { store.dispatch(setTheme(localStorage.theme)); } +if (localStorage.customTitle) { + document.title = localStorage.customTitle; +} + const App = (): JSX.Element => { return ( diff --git a/client/src/components/Apps/AppForm/AppForm.tsx b/client/src/components/Apps/AppForm/AppForm.tsx index 5ccb603..b833752 100644 --- a/client/src/components/Apps/AppForm/AppForm.tsx +++ b/client/src/components/Apps/AppForm/AppForm.tsx @@ -98,7 +98,7 @@ const AppForm = (props: ComponentProps): JSX.Element => { value={formData.url} onChange={(e) => inputChangeHandler(e)} /> - Use URL without protocol + Only urls without http[s]:// are supported diff --git a/client/src/components/Apps/AppGrid/AppGrid.tsx b/client/src/components/Apps/AppGrid/AppGrid.tsx index dff0688..cacc19c 100644 --- a/client/src/components/Apps/AppGrid/AppGrid.tsx +++ b/client/src/components/Apps/AppGrid/AppGrid.tsx @@ -6,6 +6,7 @@ import AppCard from '../AppCard/AppCard'; interface ComponentProps { apps: App[]; + totalApps?: number; } const AppGrid = (props: ComponentProps): JSX.Element => { @@ -23,9 +24,15 @@ const AppGrid = (props: ComponentProps): JSX.Element => { ) } else { - apps = ( -

You don't have any applications. You can add a new one from /application menu

- ); + if (props.totalApps) { + apps = ( +

There are no pinned applications. You can pin them from the /applications menu

+ ); + } else { + apps = ( +

You don't have any applications. You can add a new one from /applications menu

+ ); + } } return apps; diff --git a/client/src/components/Bookmarks/BookmarkForm/BookmarkForm.tsx b/client/src/components/Bookmarks/BookmarkForm/BookmarkForm.tsx index 0365d29..984c156 100644 --- a/client/src/components/Bookmarks/BookmarkForm/BookmarkForm.tsx +++ b/client/src/components/Bookmarks/BookmarkForm/BookmarkForm.tsx @@ -177,6 +177,7 @@ const BookmarkForm = (props: ComponentProps): JSX.Element => { value={formData.url} onChange={(e) => inputChangeHandler(e)} /> + Only urls without http[s]:// are supported
diff --git a/client/src/components/Bookmarks/BookmarkGrid/BookmarkGrid.tsx b/client/src/components/Bookmarks/BookmarkGrid/BookmarkGrid.tsx index 007086d..c6355c6 100644 --- a/client/src/components/Bookmarks/BookmarkGrid/BookmarkGrid.tsx +++ b/client/src/components/Bookmarks/BookmarkGrid/BookmarkGrid.tsx @@ -8,6 +8,7 @@ import BookmarkCard from '../BookmarkCard/BookmarkCard'; interface ComponentProps { categories: Category[]; + totalCategories?: number; } const BookmarkGrid = (props: ComponentProps): JSX.Element => { @@ -20,9 +21,15 @@ const BookmarkGrid = (props: ComponentProps): JSX.Element => { ); } else { - bookmarks = ( -

You don't have any bookmarks. You can add a new one from /bookmarks menu

- ); + if (props.totalCategories) { + bookmarks = ( +

There are no pinned categories. You can pin them from the /bookmarks menu

+ ); + } else { + bookmarks = ( +

You don't have any bookmarks. You can add a new one from /bookmarks menu

+ ); + } } return bookmarks; diff --git a/client/src/components/Home/Home.tsx b/client/src/components/Home/Home.tsx index 6a8ebc3..1fdd090 100644 --- a/client/src/components/Home/Home.tsx +++ b/client/src/components/Home/Home.tsx @@ -81,7 +81,10 @@ const Home = (props: ComponentProps): JSX.Element => { {props.appsLoading ? - : app.isPinned)} /> + : app.isPinned)} + totalApps={props.apps.length} + /> }
@@ -89,7 +92,10 @@ const Home = (props: ComponentProps): JSX.Element => { {props.categoriesLoading ? - : category.isPinned)} /> + : category.isPinned)} + totalCategories={props.categories.length} + /> } diff --git a/client/src/components/Settings/OtherSettings/OtherSettings.tsx b/client/src/components/Settings/OtherSettings/OtherSettings.tsx new file mode 100644 index 0000000..2d3a6cd --- /dev/null +++ b/client/src/components/Settings/OtherSettings/OtherSettings.tsx @@ -0,0 +1,88 @@ +import { useState, useEffect, ChangeEvent, FormEvent } from 'react'; +import axios from 'axios'; +import { connect } from 'react-redux'; + +import InputGroup from '../../UI/Forms/InputGroup/InputGroup'; +import Button from '../../UI/Buttons/Button/Button'; +import { createNotification } from '../../../store/actions'; +import { ApiResponse, Config, NewNotification } from '../../../interfaces'; + +interface FormState { + customTitle: string; +} + +interface ComponentProps { + createNotification: (notification: NewNotification) => void; +} + +const OtherSettings = (props: ComponentProps): JSX.Element => { + const [formData, setFormData] = useState({ + customTitle: document.title + }) + + // get initial config + useEffect(() => { + axios.get>('/api/config?keys=customTitle') + .then(data => { + let tmpFormData = { ...formData }; + + data.data.data.forEach((config: Config) => { + let value: string | number = config.value; + if (config.valueType === 'number') { + value = parseFloat(value); + } + + tmpFormData = { + ...tmpFormData, + [config.key]: value + } + }) + + setFormData(tmpFormData); + }) + .catch(err => console.log(err)); + }, []) + + const formSubmitHandler = (e: FormEvent) => { + e.preventDefault(); + + axios.put>('/api/config', formData) + .then(() => { + props.createNotification({ + title: 'Success', + message: 'Settings updated' + }) + }) + .catch((err) => console.log(err)); + + // update local page title + localStorage.setItem('customTitle', formData.customTitle); + document.title = formData.customTitle; + } + + const inputChangeHandler = (e: ChangeEvent) => { + setFormData({ + ...formData, + [e.target.name]: e.target.value + }) + } + + return ( +
formSubmitHandler(e)}> + + + inputChangeHandler(e)} + /> + + +
+ ) +} + +export default connect(null, { createNotification })(OtherSettings); \ No newline at end of file diff --git a/client/src/components/Settings/Settings.tsx b/client/src/components/Settings/Settings.tsx index 81659fa..0abea20 100644 --- a/client/src/components/Settings/Settings.tsx +++ b/client/src/components/Settings/Settings.tsx @@ -6,6 +6,7 @@ import { Container } from '../UI/Layout/Layout'; import Headline from '../UI/Headlines/Headline/Headline'; import Themer from '../Themer/Themer'; import WeatherSettings from './WeatherSettings/WeatherSettings'; +import OtherSettings from './OtherSettings/OtherSettings'; const Settings = (): JSX.Element => { return ( @@ -30,11 +31,19 @@ const Settings = (): JSX.Element => { to='/settings/weather'> Weather + + Other +
+
diff --git a/utils/initConfig.js b/utils/initConfig.js index 02f20ec..c8e43fa 100644 --- a/utils/initConfig.js +++ b/utils/initConfig.js @@ -3,8 +3,8 @@ const Config = require('../models/Config'); const initConfig = async () => { // Config keys - const keys = ['WEATHER_API_KEY', 'lat', 'long', 'isCelsius']; - const values = ['', 0, 0, true]; + const keys = ['WEATHER_API_KEY', 'lat', 'long', 'isCelsius', 'customTitle']; + const values = ['', 0, 0, true, 'Flame']; // Get config values const configPairs = await Config.findAll({