From 01a68eece6e795ea5ae5af539e73c1fb54078570 Mon Sep 17 00:00:00 2001 From: Manav Lal Date: Wed, 19 Feb 2025 14:32:26 +1300 Subject: [PATCH 1/2] Support icons --- src/api/types.ts | 1 + src/ui/features/goalmanager/GoalManager.tsx | 76 ++++++++++++++++++++- src/ui/pages/Main/goals/GoalCard.tsx | 4 ++ 3 files changed, 79 insertions(+), 2 deletions(-) diff --git a/src/api/types.ts b/src/api/types.ts index f75edad..2616d3b 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -23,6 +23,7 @@ export interface Goal { targetAmount: number balance: number targetDate: Date + icon:string|null created: Date accountId: string transactionIds: string[] diff --git a/src/ui/features/goalmanager/GoalManager.tsx b/src/ui/features/goalmanager/GoalManager.tsx index 0779dda..0e398cc 100644 --- a/src/ui/features/goalmanager/GoalManager.tsx +++ b/src/ui/features/goalmanager/GoalManager.tsx @@ -1,5 +1,5 @@ import { faCalendarAlt } from '@fortawesome/free-regular-svg-icons' -import { faDollarSign, IconDefinition } from '@fortawesome/free-solid-svg-icons' +import { faDollarSign, faSmile, IconDefinition } from '@fortawesome/free-solid-svg-icons' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { MaterialUiPickersDate } from '@material-ui/pickers/typings/date' import 'date-fns' @@ -11,8 +11,18 @@ import { selectGoalsMap, updateGoal as updateGoalRedux } from '../../../store/go import { useAppDispatch, useAppSelector } from '../../../store/hooks' import DatePicker from '../../components/DatePicker' import { Theme } from '../../components/Theme' +import { BaseEmoji } from 'emoji-mart' +import EmojiPicker from '../../components/EmojiPicker' +import AddIconButtonContainer from '../../components/AddIconButtonContainer' +import { TransparentButton } from '../../components/TransparentButton' +import GoalIcon from './GoalIcon' type Props = { goal: Goal } +type EmojiPickerContainerProps = { isOpen: boolean; hasIcon: boolean } + +const GoalIconContainer = styled.div` + display: ${(props) => (props.shouldShow ? 'flex' : 'none')}; +` export function GoalManager(props: Props) { const dispatch = useAppDispatch() @@ -22,6 +32,19 @@ export function GoalManager(props: Props) { const [targetDate, setTargetDate] = useState(null) const [targetAmount, setTargetAmount] = useState(null) + const [icon, setIcon] = useState(null) + + useEffect(() => { + setIcon(props.goal.icon) + }, [props.goal.id, props.goal.icon]) + + + const addIconOnClick = (event: React.MouseEvent) => { + event.stopPropagation() + setEmojiPickerIsOpen(true) + } + + useEffect(() => { setName(props.goal.name) setTargetDate(props.goal.targetDate) @@ -61,6 +84,27 @@ export function GoalManager(props: Props) { updateGoalApi(props.goal.id, updatedGoal) } + const [emojiPickerIsOpen, setEmojiPickerIsOpen] = useState(false) + + const hasIcon = () => icon != null + + const pickEmojiOnClick = (emoji: BaseEmoji, event: React.MouseEvent) => { + event.stopPropagation() + + setIcon(emoji.native) + setEmojiPickerIsOpen(false) + + const updatedGoal: Goal = { + ...props.goal, + icon: emoji.native ?? props.goal.icon, + name: name ?? props.goal.name, + targetDate: targetDate ?? props.goal.targetDate, + targetAmount: targetAmount ?? props.goal.targetAmount, + } + + dispatch(updateGoalRedux(updatedGoal)) + updateGoalApi(props.goal.id, updatedGoal) + } const pickDateOnChange = (date: MaterialUiPickersDate) => { if (date != null) { setTargetDate(date) @@ -106,6 +150,29 @@ export function GoalManager(props: Props) { {new Date(props.goal.created).toLocaleDateString()} + + + + + event.stopPropagation()} + > + + + + + + + + + +

Add icon

+
+ +
+
) } @@ -113,7 +180,6 @@ export function GoalManager(props: Props) { type FieldProps = { name: string; icon: IconDefinition } type AddIconButtonContainerProps = { shouldShow: boolean } type GoalIconContainerProps = { shouldShow: boolean } -type EmojiPickerContainerProps = { isOpen: boolean; hasIcon: boolean } const Field = (props: FieldProps) => ( @@ -182,3 +248,9 @@ const StringInput = styled.input` const Value = styled.div` margin-left: 2rem; ` +const EmojiPickerContainer = styled.div` + display: ${(props) => (props.isOpen ? 'flex' : 'none')}; + position: absolute; + top: ${(props) => (props.hasIcon ? '10rem' : '2rem')}; + left: 0; +` \ No newline at end of file diff --git a/src/ui/pages/Main/goals/GoalCard.tsx b/src/ui/pages/Main/goals/GoalCard.tsx index e8f6d0a..01efd81 100644 --- a/src/ui/pages/Main/goals/GoalCard.tsx +++ b/src/ui/pages/Main/goals/GoalCard.tsx @@ -9,6 +9,9 @@ import { } from '../../../../store/modalSlice' import { Card } from '../../../components/Card' +const Icon = styled.h1` + font-size: 5.5rem; +` type Props = { id: string } export default function GoalCard(props: Props) { @@ -29,6 +32,7 @@ export default function GoalCard(props: Props) { ${goal.targetAmount} {asLocaleDateString(goal.targetDate)} + {goal.icon} ) } From 8b664d396d0ec7322918aaddb9b3e3932ed727ec Mon Sep 17 00:00:00 2001 From: Manav Lal Date: Wed, 19 Feb 2025 14:41:12 +1300 Subject: [PATCH 2/2] feat: fixed addIcon button not vanishing when emoji is present --- src/ui/components/AddIconButtonContainer.tsx | 14 ++++++++++++++ src/ui/features/goalmanager/GoalManager.tsx | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 src/ui/components/AddIconButtonContainer.tsx diff --git a/src/ui/components/AddIconButtonContainer.tsx b/src/ui/components/AddIconButtonContainer.tsx new file mode 100644 index 0000000..e8dc71d --- /dev/null +++ b/src/ui/components/AddIconButtonContainer.tsx @@ -0,0 +1,14 @@ +import React, { ReactNode } from "react"; + +interface AddIconButtonContainerProps { + condition: boolean; + children: ReactNode; + wrapper?: (children: ReactNode) => JSX.Element; // Optional wrapper function +} + +const AddIconButtonContainer: React.FC = ({ condition, children, wrapper }) => { + if (!condition) return null; + return wrapper ? wrapper(children) : <>{children}; +}; + +export default AddIconButtonContainer; \ No newline at end of file diff --git a/src/ui/features/goalmanager/GoalManager.tsx b/src/ui/features/goalmanager/GoalManager.tsx index 0e398cc..d72365d 100644 --- a/src/ui/features/goalmanager/GoalManager.tsx +++ b/src/ui/features/goalmanager/GoalManager.tsx @@ -164,7 +164,7 @@ export function GoalManager(props: Props) { - +