feat(frontend): refresh indicator for titlecards / toasts

This commit is contained in:
sct
2020-09-16 12:16:21 +00:00
parent 16e74e3298
commit 4638fae336
6 changed files with 184 additions and 15 deletions

View File

@@ -42,7 +42,7 @@ const Discover: React.FC = () => {
</div>
</div>
<Slider
key="requests"
sliderKey="requests"
isLoading={!requests && !requestError}
isEmpty={!!requests && !requestError && requests.length === 0}
items={requests?.map((request) => (
@@ -61,7 +61,7 @@ const Discover: React.FC = () => {
</div>
</div>
<Slider
key="movies"
sliderKey="movies"
isLoading={!movieData && !movieError}
isEmpty={false}
items={movieData?.results.map((title) => (
@@ -87,7 +87,7 @@ const Discover: React.FC = () => {
</div>
</div>
<Slider
key="tv"
sliderKey="tv"
isLoading={!tvData && !tvError}
isEmpty={false}
items={tvData?.results.map((title) => (

View File

@@ -2,13 +2,18 @@ import React from 'react';
import TitleCard from '../TitleCard';
interface SliderProps {
key: string;
sliderKey: string;
items?: JSX.Element[];
isLoading: boolean;
isEmpty: boolean;
}
const Slider: React.FC<SliderProps> = ({ key, items, isLoading, isEmpty }) => {
const Slider: React.FC<SliderProps> = ({
sliderKey,
items,
isLoading,
isEmpty,
}) => {
return (
<div
className="overflow-x-scroll whitespace-no-wrap hide-scrollbar scrolling-touch overscroll-x-contain -ml-4 -mr-4"
@@ -16,7 +21,7 @@ const Slider: React.FC<SliderProps> = ({ key, items, isLoading, isEmpty }) => {
>
{items?.map((item, index) => (
<div
key={`${key}-${index}`}
key={`${sliderKey}-${index}`}
className="first:px-4 last:px-4 px-2 inline-block"
>
{item}

View File

@@ -1,4 +1,5 @@
import React, { useState } from 'react';
import { useToasts } from 'react-toast-notifications';
import type { MediaType } from '../../../server/models/Search';
import Available from '../../assets/available.svg';
import Requested from '../../assets/requested.svg';
@@ -39,12 +40,15 @@ const TitleCard: React.FC<TitleCardProps> = ({
mediaType,
requestId,
}) => {
const { addToast } = useToasts();
const [isUpdating, setIsUpdating] = useState(false);
const [currentStatus, setCurrentStatus] = useState(status);
const [showDetail, setShowDetail] = useState(false);
const [showRequestModal, setShowRequestModal] = useState(false);
const [showCancelModal, setShowCancelModal] = useState(false);
const request = async () => {
setIsUpdating(true);
const response = await axios.post<MediaRequest>('/api/v1/request', {
mediaId: id,
mediaType,
@@ -52,7 +56,14 @@ const TitleCard: React.FC<TitleCardProps> = ({
if (response.data) {
setCurrentStatus(response.data.status);
addToast(
<span>
<strong>{title}</strong> succesfully requested!
</span>,
{ appearance: 'success', autoDismiss: true }
);
}
setIsUpdating(false);
};
const cancelRequest = async () => {
@@ -134,6 +145,32 @@ const TitleCard: React.FC<TitleCardProps> = ({
<Unavailable className="rounded-tr-md" />
)}
</div>
<Transition
show={isUpdating}
enter="transition ease-in-out duration-300 transform opacity-0"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition ease-in-out duration-300 transform opacity-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="absolute top-0 left-0 right-0 bottom-0 bg-cool-gray-800 bg-opacity-75 z-40 text-white flex items-center justify-center rounded-lg">
<svg
className="w-10 h-10 animate-spin"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
/>
</svg>
</div>
</Transition>
<Transition
show={!image || showDetail || showRequestModal || showCancelModal}

View File

@@ -2,6 +2,7 @@ import React from 'react';
import '../styles/globals.css';
import App, { AppInitialProps } from 'next/app';
import { SWRConfig } from 'swr';
import { ToastProvider } from 'react-toast-notifications';
import Layout from '../components/Layout';
import { UserContext } from '../context/UserContext';
import axios from 'axios';
@@ -70,7 +71,9 @@ class CoreApp extends App<AppProps> {
fetcher: (url) => axios.get(url).then((res) => res.data),
}}
>
<UserContext initialUser={user}>{component}</UserContext>
<ToastProvider>
<UserContext initialUser={user}>{component}</UserContext>
</ToastProvider>
</SWRConfig>
);
}