diff --git a/package-lock.json b/package-lock.json index d8e6ff1a..36f21a34 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6498,9 +6498,9 @@ } }, "@types/eslint": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.4.tgz", - "integrity": "sha512-YCY4kzHMsHoyKspQH+nwSe+70Kep7Vjt2X+dZe5Vs2vkRudqtoFoUIv1RlJmZB8Hbp7McneupoZij4PadxsK5Q==", + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.5.tgz", + "integrity": "sha512-Dc6ar9x16BdaR3NSxSF7T4IjL9gxxViJq8RmFd+2UAyA+K6ck2W+gUwfgpG/y9TPyUuBL35109bbULpEynvltA==", "requires": { "@types/estree": "*", "@types/json-schema": "*" @@ -24956,6 +24956,14 @@ "tree-changes": "^0.5.1" } }, + "react-kawaii": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/react-kawaii/-/react-kawaii-0.16.0.tgz", + "integrity": "sha512-ZD8QkK8pQbLdV391aJ4CAwuFq2rxVeRhYIsyj9d9q68aobFjcs3UwmGOFgSLWoI642ecXJD/4wBscYXMCcCWJw==", + "requires": { + "prop-types": "^15.6.2" + } + }, "react-lifecycles-compat": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", diff --git a/package.json b/package.json index 5237362a..dd0244e5 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "@types/babel__core": "^7.1.12", "@types/classnames": "^2.2.11", "@types/debug": "^4.1.5", - "@types/eslint": "^7.2.4", + "@types/eslint": "^7.2.5", "@types/eslint-plugin-prettier": "^3.1.0", "@types/faker": "^5.1.4", "@types/jest": "^26.0.15", @@ -65,6 +65,7 @@ "react-i18next": "^11.7.3", "react-if": "^4.0.1", "react-joyride": "^2.1.1", + "react-kawaii": "^0.16.0", "react-mailto.js": "^2.1.0", "react-redux": "^7.2.2", "react-redux-firebase": "^3.0.5", diff --git a/src/@types/libraries.d.ts b/src/@types/libraries.d.ts index 2043c094..18e9d0b8 100644 --- a/src/@types/libraries.d.ts +++ b/src/@types/libraries.d.ts @@ -1,2 +1,3 @@ declare module 'react-use-toggle'; +declare module 'react-kawaii'; declare module 'react-firebaseui-localized'; diff --git a/src/RouterAndDataLoader.tsx b/src/RouterAndDataLoader.tsx index 7d2a1274..7087bed2 100644 --- a/src/RouterAndDataLoader.tsx +++ b/src/RouterAndDataLoader.tsx @@ -135,7 +135,12 @@ export default memo((props: { children?: JSX.Element }) => { - + {/* TODO use a container instead of dumb component. */} + diff --git a/src/components/ui/EmotionIconButton/EmotionIconButton.stories.tsx b/src/components/ui/EmotionIconButton/EmotionIconButton.stories.tsx new file mode 100644 index 00000000..8a3a34d6 --- /dev/null +++ b/src/components/ui/EmotionIconButton/EmotionIconButton.stories.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { sections } from '../../storybookContants'; +import { + EmotionIconButton, + EmotionIconButtonProps, +} from '../EmotionIconButton'; + +export default { + component: EmotionIconButton, + title: `${sections.ui}EmotionIconButton`, +}; + +const props = { + type: 'happy_face', + onClick: console.log, +} as EmotionIconButtonProps; + +export const Demo = (args) => ; +Demo.args = props; diff --git a/src/components/ui/EmotionIconButton/EmotionIconButton.tsx b/src/components/ui/EmotionIconButton/EmotionIconButton.tsx new file mode 100644 index 00000000..e00c5ec4 --- /dev/null +++ b/src/components/ui/EmotionIconButton/EmotionIconButton.tsx @@ -0,0 +1,50 @@ +import { IconButton, useTheme } from '@material-ui/core'; +import React, { memo } from 'react'; +import { Planet } from 'react-kawaii'; + +type EmotionTypes = 'happy_face' | 'sad_face'; + +export interface EmotionIconButtonProps { + type: EmotionTypes; + onClick?: ( + event: React.MouseEvent, + ) => void; +} +const EmotionIconButton = memo(function EmotionIconButton({ + type, + onClick, +}: EmotionIconButtonProps) { + const theme = useTheme(); + + function geticon() { + const kawaiiIconSize = 75; + switch (type) { + case 'happy_face': + return ( + + ); + case 'sad_face': + return ( + + ); + } + } + + return ( + + {geticon()} + + ); +}); + +EmotionIconButton.displayName = 'EmotionIconButton'; + +export { EmotionIconButton }; diff --git a/src/components/ui/EmotionIconButton/index.ts b/src/components/ui/EmotionIconButton/index.ts new file mode 100644 index 00000000..b3ad26be --- /dev/null +++ b/src/components/ui/EmotionIconButton/index.ts @@ -0,0 +1 @@ +export * from './EmotionIconButton'; diff --git a/src/components/ui/Icon.tsx b/src/components/ui/Icon.tsx index 27b21831..f59067fc 100644 --- a/src/components/ui/Icon.tsx +++ b/src/components/ui/Icon.tsx @@ -1,11 +1,8 @@ -import { Box, Theme } from '@material-ui/core'; +import { Box } from '@material-ui/core'; import SatisfiedIcon from '@material-ui/icons/SentimentSatisfiedAlt'; import DissatisfiedIcon from '@material-ui/icons/SentimentVeryDissatisfied'; -import { makeStyles } from '@material-ui/styles'; import React, { memo } from 'react'; -const useStyles = makeStyles((theme: Theme) => ({ root: {} })); - export type Icons = 'happy_face' | 'sad_face'; export interface IconProps { @@ -17,7 +14,6 @@ const Icon = memo(function Icon({ code, size = 'default', }: IconProps) { - const classes = useStyles(); function getIconByCode() { switch (code) { case 'happy_face': @@ -28,7 +24,7 @@ const Icon = memo(function Icon({ return ; } } - return {getIconByCode()}; + return {getIconByCode()}; }); Icon.displayName = 'Icon'; diff --git a/src/components/unsorted/Autocomplete/Autocomplete.tsx b/src/components/unsorted/Autocomplete/Autocomplete.tsx index 6908389d..06785b7a 100644 --- a/src/components/unsorted/Autocomplete/Autocomplete.tsx +++ b/src/components/unsorted/Autocomplete/Autocomplete.tsx @@ -1,11 +1,8 @@ -import React, { memo } from 'react'; -import { makeStyles } from '@material-ui/styles'; -import { Box, TextField, Theme } from '@material-ui/core'; +import { Box, TextField } from '@material-ui/core'; import MuiAutocomplete, { createFilterOptions, } from '@material-ui/lab/Autocomplete'; - -const useStyles = makeStyles((theme: Theme) => ({ root: {} })); +import React, { memo } from 'react'; interface OptionType { value: any; @@ -24,10 +21,8 @@ const filter = createFilterOptions(); const Autocomplete = memo(function Autocomplete( props: AutocompleteProps, ) { - const classes = useStyles(); - return ( - + i.label} filterOptions={(options, params) => { - console.log('params: ', params); const filtered = filter(options, params); // Suggest the creation of a new value @@ -78,16 +72,15 @@ const Autocomplete = memo(function Autocomplete( } if (typeof newValue === 'string') { - props.onChange(newValue); - } else { - console.log('on change newValue: ', newValue); - // TODO: rename this. - if (newValue?.inputValue) { - newValue.label = newValue.inputValue; - } - console.log('newValue.value: ', newValue?.value); - props.onChange(newValue); + return props.onChange(newValue); } + + // TODO: rename this. + if (newValue?.inputValue) { + newValue.label = newValue.inputValue; + } + + props.onChange(newValue); }} /> diff --git a/src/components/unsorted/WhatDoYouFeelAboutTheTask.tsx b/src/components/unsorted/WhatDoYouFeelAboutTheTask.tsx index 9ecdc901..88d69580 100644 --- a/src/components/unsorted/WhatDoYouFeelAboutTheTask.tsx +++ b/src/components/unsorted/WhatDoYouFeelAboutTheTask.tsx @@ -3,31 +3,22 @@ import { Card, CardContent, CardHeader, - Fab, Grid, - Theme, } from '@material-ui/core'; -import SatisfiedIcon from '@material-ui/icons/SentimentSatisfiedAlt'; -import DissatisfiedIcon from '@material-ui/icons/SentimentVeryDissatisfied'; -import { makeStyles } from '@material-ui/styles'; import classNames from 'classnames'; import React, { memo } from 'react'; import { Link, useRouteMatch } from 'react-router-dom'; import { useTypedTranslate } from '../../services'; - -const useStyles = makeStyles((theme: Theme) => ({ - root: {}, -})); +import { EmotionIconButton } from '../ui/EmotionIconButton'; interface Props { className?: string; } const WhatDoYouFeelAboutTheTask = memo((props: Props) => { - const classes = useStyles(); const t = useTypedTranslate(); const { url } = useRouteMatch() || { url: '' }; - const rootClasses = classNames(classes.root, props.className); + const rootClasses = classNames(props.className); return ( @@ -36,22 +27,14 @@ const WhatDoYouFeelAboutTheTask = memo((props: Props) => { - - - + + + - - - + + + diff --git a/src/components/unsorted/WhatDoYouFeelSlider.tsx b/src/components/unsorted/WhatDoYouFeelSlider.tsx index a037fb72..b2a82890 100644 --- a/src/components/unsorted/WhatDoYouFeelSlider.tsx +++ b/src/components/unsorted/WhatDoYouFeelSlider.tsx @@ -1,7 +1,6 @@ +import { Box, Grid, Slider } from '@material-ui/core'; import React, { memo } from 'react'; -import { Box, Fab, Grid, Slider } from '@material-ui/core'; -import SatisfiedIcon from '@material-ui/icons/SentimentSatisfiedAlt'; -import DissatisfiedIcon from '@material-ui/icons/SentimentVeryDissatisfied'; +import { EmotionIconButton } from '../ui/EmotionIconButton'; export interface WhatDoYouFeelSliderProps { onChange: (value: number) => void; @@ -15,9 +14,7 @@ const WhatDoYouFeelSlider = memo(function WhatDoYouFeelSlider( - - - + @@ -36,9 +33,7 @@ const WhatDoYouFeelSlider = memo(function WhatDoYouFeelSlider( - - - + diff --git a/src/pages/FocusModePage/FocusModePage.stories.tsx b/src/pages/FocusModePage/FocusModePage.stories.tsx index 7b74069d..8022cec1 100644 --- a/src/pages/FocusModePage/FocusModePage.stories.tsx +++ b/src/pages/FocusModePage/FocusModePage.stories.tsx @@ -10,7 +10,8 @@ export default { const props = { isLoading: false, - tasks: tasksMock, + tasksToList: tasksMock, + tasksForAutoComplete: tasksMock, } as FocusModePageProps; export const Demo = (args) => ; diff --git a/src/pages/FocusModePage/FocusModePage.tsx b/src/pages/FocusModePage/FocusModePage.tsx index 117bd140..67712d5f 100644 --- a/src/pages/FocusModePage/FocusModePage.tsx +++ b/src/pages/FocusModePage/FocusModePage.tsx @@ -4,20 +4,34 @@ import { TasksList } from '../../components/tasks/TasksList'; import { WhatDoYouFeelSlider } from '../../components/unsorted/WhatDoYouFeelSlider'; import { Task } from '../../entities/Task'; import { If } from 'react-if'; +import { Autocomplete } from '../../components/unsorted/Autocomplete'; export interface FocusModePageProps { - tasks: Task[]; isLoading: boolean; + tasksToList: Task[]; + tasksForAutoComplete: Task[]; } const FocusModePage = memo(function FocusModePage({ - tasks, - isLoading, + isLoading = false, + tasksToList = [], + tasksForAutoComplete = [], }: FocusModePageProps) { + const autocompleteOptions = tasksForAutoComplete.map((task) => ({ + value: task, + label: task.name, + })); + return ( + - + diff --git a/src/pages/TaskPage/TaskPageContainer.tsx b/src/pages/TaskPage/TaskPageContainer.tsx index 6904ae02..fb05dcbd 100644 --- a/src/pages/TaskPage/TaskPageContainer.tsx +++ b/src/pages/TaskPage/TaskPageContainer.tsx @@ -32,7 +32,6 @@ import { import { toggleTasksDoneTodayNotification } from '../../store/uiSlice'; import TaskPage, { TaskPageProps } from './TaskPage'; import { deleteTask as deleteTaskRepo } from '../../repositories/deleteTask'; -import { Task } from '../../entities/Task'; const componentName = 'TaskPageContainer'; const log = debug(componentName); @@ -163,27 +162,25 @@ const Container = memo(() => { async function deleteTask(options: deleteTaskArguments = {}) { log('deleteTask is running.'); toggleLoading(true); - try { - await Promise.all([ - deleteTaskRepo(taskId), - addPointsWithSideEffects(userId, 10), - TaskService.activateNextTask({ - nextTaskId, - currentTasks: tasks, - }), - ]); - showSnackbarAfterTaskDelete({ - deletedTask: task, - pointsToRemoveFromUser: options.pointsToAdd || 10, - message: options.snackbarMessage || t('successfullyDeleted'), - }); - history.replace(nextTaskId ? '/tasks/active' : '/'); - } catch (error) { - handleErrors(error); - history.replace('/tasks/active'); - } finally { - toggleLoading(false); - } + return Promise.all([ + deleteTaskRepo(taskId), + addPointsWithSideEffects(userId, 10), + TaskService.activateNextTask({ + nextTaskId, + currentTasks: tasks, + }), + ]) + .then(() => { + Snackbar.addToQueue( + options.snackbarMessage || t('successfullyDeleted'), + ); + history.replace(nextTaskId ? '/tasks/active' : '/'); + }) + .catch((error) => { + handleErrors(error); + history.replace('/tasks/active'); + }) + .finally(toggleLoading); } async function updateDailyStreak() { @@ -199,30 +196,6 @@ const Container = memo(() => { }); } - function showSnackbarAfterTaskDelete({ - deletedTask, - pointsToRemoveFromUser, - message, - }: { - message: string; - deletedTask: Task; - pointsToRemoveFromUser: number; - }) { - // function undoTaskDeletion() { - // return Promise.all([ - // upsertTask(deletedTask, deletedTask.id), - // addPointsWithSideEffects( - // deletedTask.userId, - // pointsToRemoveFromUser * -1, - // ), - // ]) - // .then(() => history.replace(`/tasks/${deletedTask.id}`)) - // .catch(handleErrors); - // } - - Snackbar.addToQueue(message); - } - const mergedProps = { taskId, updateTask, diff --git a/templates/DumbComponent.stories.txt b/templates/DumbComponent.stories.txt index eb482913..04fb6654 100644 --- a/templates/DumbComponent.stories.txt +++ b/templates/DumbComponent.stories.txt @@ -1,13 +1,13 @@ import React from 'react'; import { sections } from '../storybookContants'; -import { {{pascalCase name}} } from '../{{pascalCase name}}'; +import { {{pascalCase name}}, {{name}}Props } from '../../{{pascalCase name}}'; export default { component: {{ pascalCase name }}, title: `${sections.unsorted}{{pascalCase name}}`, }; -const props = {} +const props = {} as {{name}}Props export const Demo = args => <{{ pascalCase name }} {...args} /> Demo.args = props