Empty sections will be hidden from guests. Fixed temperature value rounding. Added welcome message

This commit is contained in:
Paweł Malak 2021-11-22 12:29:47 +01:00
parent 882f011d07
commit d110d9b732
11 changed files with 80 additions and 71 deletions

View file

@ -1,7 +1,9 @@
### v2.0.2 (TBA)
- Added support for .ico files for custom icons ([#209](https://github.com/pawelmalak/flame/issues/209))
- Added option to pin apps and categories directly from table view
- Empty apps and categories sections will now be hidden from guests ([#210](https://github.com/pawelmalak/flame/issues/210))
- Fixed bug with fahrenheit degrees being displayed as float ([#221](https://github.com/pawelmalak/flame/issues/221))
- Added option to change visibilty of apps and categories directly from table view
- Password input will now autofocus when visiting /settings/app
### v2.0.1 (2021-11-19)
- Added option to display humidity in the weather widget ([#136](https://github.com/pawelmalak/flame/issues/136))

View file

@ -20,21 +20,3 @@
grid-template-columns: repeat(4, 1fr);
}
}
.GridMessage {
color: var(--color-primary);
}
.GridMessage a {
color: var(--color-accent);
font-weight: 600;
}
.AppsMessage {
color: var(--color-primary);
}
.AppsMessage a {
color: var(--color-accent);
font-weight: 600;
}

View file

@ -3,6 +3,7 @@ import { Link } from 'react-router-dom';
import { App } from '../../../interfaces/App';
import { AppCard } from '../AppCard/AppCard';
import { Message } from '../../UI';
interface Props {
apps: App[];
@ -13,7 +14,10 @@ interface Props {
export const AppGrid = (props: Props): JSX.Element => {
let apps: JSX.Element;
if (props.apps.length > 0) {
if (props.searching || props.apps.length) {
if (!props.apps.length) {
apps = <Message>No apps match your search criteria</Message>;
} else {
apps = (
<div className={classes.AppGrid}>
{props.apps.map((app: App): JSX.Element => {
@ -21,28 +25,21 @@ export const AppGrid = (props: Props): JSX.Element => {
})}
</div>
);
} else {
if (props.totalApps) {
if (props.searching) {
apps = (
<p className={classes.AppsMessage}>
No apps match your search criteria
</p>
);
} else {
apps = (
<p className={classes.AppsMessage}>
There are no pinned applications. You can pin them from the{' '}
<Link to="/applications">/applications</Link> menu
</p>
);
}
} else {
if (props.totalApps) {
apps = (
<p className={classes.AppsMessage}>
<Message>
There are no pinned applications. You can pin them from the{' '}
<Link to="/applications">/applications</Link> menu
</Message>
);
} else {
apps = (
<Message>
You don't have any applications. You can add a new one from{' '}
<Link to="/applications">/applications</Link> menu
</p>
</Message>
);
}
}

View file

@ -20,12 +20,3 @@
grid-template-columns: repeat(4, 1fr);
}
}
.BookmarksMessage {
color: var(--color-primary);
}
.BookmarksMessage a {
color: var(--color-accent);
font-weight: 600;
}

View file

@ -5,6 +5,7 @@ import classes from './BookmarkGrid.module.css';
import { Category } from '../../../interfaces';
import { BookmarkCard } from '../BookmarkCard/BookmarkCard';
import { Message } from '../../UI';
interface Props {
categories: Category[];
@ -17,11 +18,7 @@ export const BookmarkGrid = (props: Props): JSX.Element => {
if (props.categories.length) {
if (props.searching && !props.categories[0].bookmarks.length) {
bookmarks = (
<p className={classes.BookmarksMessage}>
No bookmarks match your search criteria
</p>
);
bookmarks = <Message>No bookmarks match your search criteria</Message>;
} else {
bookmarks = (
<div className={classes.BookmarkGrid}>
@ -36,17 +33,17 @@ export const BookmarkGrid = (props: Props): JSX.Element => {
} else {
if (props.totalCategories) {
bookmarks = (
<p className={classes.BookmarksMessage}>
<Message>
There are no pinned categories. You can pin them from the{' '}
<Link to="/bookmarks">/bookmarks</Link> menu
</p>
</Message>
);
} else {
bookmarks = (
<p className={classes.BookmarksMessage}>
<Message>
You don't have any bookmarks. You can add a new one from{' '}
<Link to="/bookmarks">/bookmarks</Link> menu
</p>
</Message>
);
}
}

View file

@ -11,7 +11,7 @@ import { actionCreators } from '../../store';
import { App, Category } from '../../interfaces';
// UI
import { Icon, Container, SectionHeadline, Spinner } from '../UI';
import { Icon, Container, SectionHeadline, Spinner, Message } from '../UI';
// CSS
import classes from './Home.module.css';
@ -30,6 +30,7 @@ export const Home = (): JSX.Element => {
apps: { apps, loading: appsLoading },
bookmarks: { categories, loading: bookmarksLoading },
config: { config },
auth: { isAuthenticated },
} = useSelector((state: State) => state);
const dispatch = useDispatch();
@ -100,7 +101,18 @@ export const Home = (): JSX.Element => {
<Header />
{!config.hideApps ? (
{!isAuthenticated &&
!apps.some((a) => a.isPinned) &&
!categories.some((c) => c.isPinned) ? (
<Message>
Welcome to Flame! Go to <Link to="/settings/app">/settings</Link>,
login and start customizing your new homepage
</Message>
) : (
<></>
)}
{!config.hideApps && (isAuthenticated || apps.some((a) => a.isPinned)) ? (
<Fragment>
<SectionHeadline title="Applications" link="/applications" />
{appsLoading ? (
@ -119,10 +131,11 @@ export const Home = (): JSX.Element => {
<div className={classes.HomeSpace}></div>
</Fragment>
) : (
<div></div>
<></>
)}
{!config.hideCategories ? (
{!config.hideCategories &&
(isAuthenticated || categories.some((c) => c.isPinned)) ? (
<Fragment>
<SectionHeadline title="Bookmarks" link="/bookmarks" />
{bookmarksLoading ? (
@ -142,7 +155,7 @@ export const Home = (): JSX.Element => {
)}
</Fragment>
) : (
<div></div>
<></>
)}
<Link to="/settings" className={classes.SettingsButton}>

View file

@ -1,4 +1,4 @@
import { FormEvent, Fragment, useEffect, useState } from 'react';
import { FormEvent, Fragment, useEffect, useState, useRef } from 'react';
// Redux
import { useSelector, useDispatch } from 'react-redux';
@ -23,6 +23,12 @@ export const AuthForm = (): JSX.Element => {
duration: '14d',
});
const passwordInputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
passwordInputRef.current?.focus();
}, []);
useEffect(() => {
if (token) {
const decoded = decodeToken(token);
@ -52,6 +58,7 @@ export const AuthForm = (): JSX.Element => {
name="password"
placeholder="••••••"
autoComplete="current-password"
ref={passwordInputRef}
value={formData.password}
onChange={(e) =>
setFormData({ ...formData, password: e.target.value })

View file

@ -0,0 +1,8 @@
.message {
color: var(--color-primary);
}
.message a {
color: var(--color-accent);
font-weight: 600;
}

View file

@ -0,0 +1,11 @@
import { ReactNode } from 'react';
import classes from './Message.module.css';
interface Props {
children: ReactNode;
}
export const Message = ({ children }: Props): JSX.Element => {
return <p className={classes.message}>{children}</p>;
};

View file

@ -12,3 +12,4 @@ export * from './Forms/InputGroup/InputGroup';
export * from './Forms/ModalForm/ModalForm';
export * from './Buttons/ActionButton/ActionButton';
export * from './Buttons/Button/Button';
export * from './Text/Message/Message';

View file

@ -71,7 +71,7 @@ export const WeatherWidget = (): JSX.Element => {
{config.isCelsius ? (
<span>{weather.tempC}°C</span>
) : (
<span>{weather.tempF}°F</span>
<span>{Math.round(weather.tempF)}°F</span>
)}
{/* ADDITIONAL DATA */}