From 2a597d5cf02510cc669ef7f359384c244f28dbe7 Mon Sep 17 00:00:00 2001 From: dexter0552 Date: Wed, 8 Apr 2026 16:32:47 +0530 Subject: [PATCH 1/2] Added icon field and integrated emoji picker in Goal Manager --- package-lock.json | 17 +++++------ package.json | 5 ++-- src/api/types.ts | 1 + src/ui/components/EmojiPicker.tsx | 1 + src/ui/features/goalmanager/GoalIcon.tsx | 2 +- src/ui/features/goalmanager/GoalManager.tsx | 32 +++++++++++++++++++++ 6 files changed, 46 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 240aecf..cbf52f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,6 @@ "@material-ui/core": "^4.12.4", "@material-ui/pickers": "^3.3.10", "@reduxjs/toolkit": "^1.5.1", - "@types/emoji-mart": "^3.0.5", "@types/node": "^17.0.41", "@types/react": "^16.9.0", "@types/react-redux": "^7.1.7", @@ -35,7 +34,7 @@ "web-vitals": "^2.1.4" }, "devDependencies": { - "@types/emoji-mart": "^3.0.9", + "@types/emoji-mart": "^3.0.14", "@types/react-dom": "^18.0.5", "@types/styled-components": "^5.1.25" } @@ -3699,10 +3698,11 @@ } }, "node_modules/@types/emoji-mart": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@types/emoji-mart/-/emoji-mart-3.0.9.tgz", - "integrity": "sha512-qdBo/2Y8MXaJ/2spKjDZocuq79GpnOhkwMHnK2GnVFa8WYFgfA+ei6sil3aeWQPCreOKIx9ogPpR5+7MaOqYAA==", + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/@types/emoji-mart/-/emoji-mart-3.0.14.tgz", + "integrity": "sha512-/vMkVnet466bK37ugf2jry9ldCZklFPXYMB2m+qNo3vkP2I7L0cvtNFPKAjfcHgPg9Z8pbYqVqZn7AgsC0qf+g==", "dev": true, + "license": "MIT", "dependencies": { "@types/react": "*" } @@ -6611,6 +6611,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/emoji-mart/-/emoji-mart-3.0.1.tgz", "integrity": "sha512-sxpmMKxqLvcscu6mFn9ITHeZNkGzIvD0BSNFE/LJESPbCA8s1jM6bCDPjWbV31xHq7JXaxgpHxLB54RCbBZSlg==", + "license": "BSD-3-Clause", "dependencies": { "@babel/runtime": "^7.0.0", "prop-types": "^15.6.0" @@ -19308,9 +19309,9 @@ } }, "@types/emoji-mart": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@types/emoji-mart/-/emoji-mart-3.0.9.tgz", - "integrity": "sha512-qdBo/2Y8MXaJ/2spKjDZocuq79GpnOhkwMHnK2GnVFa8WYFgfA+ei6sil3aeWQPCreOKIx9ogPpR5+7MaOqYAA==", + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/@types/emoji-mart/-/emoji-mart-3.0.14.tgz", + "integrity": "sha512-/vMkVnet466bK37ugf2jry9ldCZklFPXYMB2m+qNo3vkP2I7L0cvtNFPKAjfcHgPg9Z8pbYqVqZn7AgsC0qf+g==", "dev": true, "requires": { "@types/react": "*" diff --git a/package.json b/package.json index 87958ce..9291828 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,6 @@ "@material-ui/core": "^4.12.4", "@material-ui/pickers": "^3.3.10", "@reduxjs/toolkit": "^1.5.1", - "@types/emoji-mart": "^3.0.5", "@types/node": "^17.0.41", "@types/react": "^16.9.0", "@types/react-redux": "^7.1.7", @@ -55,8 +54,8 @@ ] }, "devDependencies": { - "@types/emoji-mart": "^3.0.9", + "@types/emoji-mart": "^3.0.14", "@types/react-dom": "^18.0.5", "@types/styled-components": "^5.1.25" } -} \ No newline at end of file +} diff --git a/src/api/types.ts b/src/api/types.ts index f75edad..5beff48 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -20,6 +20,7 @@ export interface Application { export interface Goal { id: string name: string + icon?: string targetAmount: number balance: number targetDate: Date diff --git a/src/ui/components/EmojiPicker.tsx b/src/ui/components/EmojiPicker.tsx index 00bb54d..58ba649 100644 --- a/src/ui/components/EmojiPicker.tsx +++ b/src/ui/components/EmojiPicker.tsx @@ -3,6 +3,7 @@ import 'emoji-mart/css/emoji-mart.css' import { useAppSelector } from '../../store/hooks' import { selectMode } from '../../store/themeSlice' + type Props = { onClick: (emoji: BaseEmoji, event: React.MouseEvent) => void } export default function EmojiPicker(props: Props) { diff --git a/src/ui/features/goalmanager/GoalIcon.tsx b/src/ui/features/goalmanager/GoalIcon.tsx index b5a0d75..b10a77f 100644 --- a/src/ui/features/goalmanager/GoalIcon.tsx +++ b/src/ui/features/goalmanager/GoalIcon.tsx @@ -8,7 +8,7 @@ type Props = { icon: string | null; onClick: (e: React.MouseEvent) => void } export default function GoalIcon(props: Props) { return ( - {props.icon} + {props.icon ?? "🎯"} ) } diff --git a/src/ui/features/goalmanager/GoalManager.tsx b/src/ui/features/goalmanager/GoalManager.tsx index 0779dda..c8df43b 100644 --- a/src/ui/features/goalmanager/GoalManager.tsx +++ b/src/ui/features/goalmanager/GoalManager.tsx @@ -11,11 +11,30 @@ 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 EmojiPicker from '../../components/EmojiPicker' type Props = { goal: Goal } export function GoalManager(props: Props) { const dispatch = useAppDispatch() + const [icon, setIcon] = useState(props.goal.icon ?? null) + const [showPicker, setShowPicker] = useState(false) + + const handleEmojiClick = (emoji: any, event: React.MouseEvent) => { + const selectedEmoji = emoji.native + + setIcon(selectedEmoji) + setShowPicker(false) + + const updatedGoal: Goal = { + ...props.goal, + icon: selectedEmoji, + } + + dispatch(updateGoalRedux(updatedGoal)) + updateGoalApi(props.goal.id, updatedGoal) + } + const goal = useAppSelector(selectGoalsMap)[props.goal.id] const [name, setName] = useState(null) @@ -77,6 +96,19 @@ export function GoalManager(props: Props) { return ( + + + + {showPicker && ( + + )} + {icon && ( +
+ {icon} +
+ )} From 74c9001df873c32cd86fe82450c32c09057f83e8 Mon Sep 17 00:00:00 2001 From: dexter0552 Date: Wed, 8 Apr 2026 17:19:21 +0530 Subject: [PATCH 2/2] Completed emoji picker and goal icon feature --- src/api/lib.ts | 3 +-- src/ui/features/goalmanager/GoalManager.zip | Bin 0 -> 1887 bytes 2 files changed, 1 insertion(+), 2 deletions(-) create mode 100644 src/ui/features/goalmanager/GoalManager.zip diff --git a/src/api/lib.ts b/src/api/lib.ts index 3c593ca..a2b0f5c 100644 --- a/src/api/lib.ts +++ b/src/api/lib.ts @@ -2,8 +2,7 @@ import axios from 'axios' import { user } from '../data/user' import { Goal, Transaction, User } from './types' -export const API_ROOT = 'https://fencer-commbank.azurewebsites.net' - +export const API_ROOT = 'http://localhost:5203' export async function getUser(): Promise { try { const response = await axios.get(`${API_ROOT}/api/User/${user.id}`) diff --git a/src/ui/features/goalmanager/GoalManager.zip b/src/ui/features/goalmanager/GoalManager.zip new file mode 100644 index 0000000000000000000000000000000000000000..209eab56e239348f96e8017e0a602e7da05c8164 GIT binary patch literal 1887 zcmai#dpHvcAIIl1q+F^YOm54RriEE^UnL1Ahtg7GNQ~Dlav9ah*jNZ*Xe~r6F_+wL zMLVrgO179xr<^faEM;Zo9G&NVp7;Fse!tK2yF9<|^ZWPX?V+Fu0;p`5m7aAL@Gofq zi~w#iLI3dziVg}3yRS9S(r=FQ?{VL zoLxRXR61j-&|aiyV0$33+Xmkw|IFWJdVRNiM!WeK{t)z0eC(9nrMx;|8J6EFbt~ z(a$(cg`Cl3n9G zhvn-TB53J*-GW~$LrH!Q$l5pcRYd$#<_)I6 zQ~y5B_8r56ojN*aAg;no33e6b+(y4EXc1(rpO1?zT^|E+e{af=my}LYib9 z!?G3;QT%!=DtK+4SgdN@dC+=)U?oAWFNm2}ByjAxDXVd8!o343t#)jOymNH>&%|N^V$$5Tj4Sd}W$}IKP4y98#OK7|WQ}Yo}lj ztzQv`BY#j**s*J!zn#LJF4XbFX*C@AN?H>SI(V}$(*Ib-1in}48rw-2u-|6!Wrls) zgKS~^ReKXp>Jn9Tn>YToZPiLNS8%>W%TaI2m&dZDxiR#elQ<(@U0sohgWs!@IG#x4 zdPGA)ev2($>M`ZG{Zu4l1)6;i;#M%No1)Wb`ope*#wH3ENk80cKyR`XksVaYVBYIx zD+wE$M;KPnDR+%8e=OEk32+~mm+g?mf;FZ$3=$u-x{FyEUus7pZRdk?M-mF@WLYF@yjJ6F> zyzb|0YqZwW4v7t$?K6q6$G(&$Cdvkgw2T*bs`twRE>8r+(L1Rta|S3xN4wFxX~9{Y zZx`KoLu;#BtVe2RBYRu)H#5ah?F7`Zv^=skAMES4>`CtWlv%7*`uypx1p%s7yI;pb z;_oTvZ;fHpNr7~3{g)LrLVSG4q|@`Z%I(HmH2zR@nKRHa#%N zvz1aqz^K1Gta7C32DcsmM=B*HBsLcUn*n8X_{f&!VS&0D4zy=#sdPSgXc9Znh6Rt5 zB8SGb5AJaA5~n4$xCX7@NhW)O%JVu_ap7hS`J}N|4U7N-JiFnJe(qBWhu)fkJ@N=B zyJb$2q&DvVoWfcDq8XZVRvbxL-+z<=5qb=1MuYBix+d2!#gy}}6}&4(xZ}$uaCp(= zlP%rxE?Q5Ai~CTOt*ETUkBezBDpZ@3@iEw}LjT-C_{v%3PhE4@8(;5>bD<2ksfxQ0 z-c^9$UMUgMb^P|Ya`}{9jAtDAM5H=*Sbt0TTT!hpX7tM($_#S$3Pc!ty+HHukntXt zk#nqc8x5mt>}%qf?v$ilgG#<_Q=-QYHJHf8iTe9e^bBTTRY0HBdafqdnfxqiuWttl zWYG!TH-zc9C8{-7qXCq-e`?P6z|Mw~+Ci6DQdzgIAkz>n-% za`yI6R@u`