Empty sections will be hidden from guests. Fixed temperature value rounding. Added welcome message
This commit is contained in:
parent
882f011d07
commit
d110d9b732
11 changed files with 80 additions and 71 deletions
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,12 +20,3 @@
|
|||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
.BookmarksMessage {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.BookmarksMessage a {
|
||||
color: var(--color-accent);
|
||||
font-weight: 600;
|
||||
}
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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}>
|
||||
|
|
|
@ -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 })
|
||||
|
|
8
client/src/components/UI/Text/Message/Message.module.css
Normal file
8
client/src/components/UI/Text/Message/Message.module.css
Normal file
|
@ -0,0 +1,8 @@
|
|||
.message {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.message a {
|
||||
color: var(--color-accent);
|
||||
font-weight: 600;
|
||||
}
|
11
client/src/components/UI/Text/Message/Message.tsx
Normal file
11
client/src/components/UI/Text/Message/Message.tsx
Normal 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>;
|
||||
};
|
|
@ -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';
|
||||
|
|
|
@ -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 */}
|
||||
|
|
Loading…
Reference in a new issue