From 0f7efd83030de487ecff376043682236326c916a Mon Sep 17 00:00:00 2001 From: Garima Meena Date: Fri, 26 Jun 2026 23:19:41 +0530 Subject: [PATCH 1/3] Add goal icons and emoji picker --- package-lock.json | 1 + src/api/types.ts | 1 + src/ui/features/goalmanager/GoalManager.tsx | 12 ++++++++++++ src/ui/pages/Main/goals/GoalCard.tsx | 4 ++++ tsconfig.json | 2 +- 5 files changed, 19 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 240aecf..94349f8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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" diff --git a/src/api/types.ts b/src/api/types.ts index f75edad..6193f2a 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -27,6 +27,7 @@ export interface Goal { accountId: string transactionIds: string[] tagIds: string[] + icon?: string } export interface Tag { diff --git a/src/ui/features/goalmanager/GoalManager.tsx b/src/ui/features/goalmanager/GoalManager.tsx index 0779dda..634efc5 100644 --- a/src/ui/features/goalmanager/GoalManager.tsx +++ b/src/ui/features/goalmanager/GoalManager.tsx @@ -11,6 +11,7 @@ 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 { Picker } from 'emoji-mart' type Props = { goal: Goal } export function GoalManager(props: Props) { @@ -21,6 +22,7 @@ export function GoalManager(props: Props) { const [name, setName] = useState(null) const [targetDate, setTargetDate] = useState(null) const [targetAmount, setTargetAmount] = useState(null) + const [emoji, setEmoji] = useState("🎯") useEffect(() => { setName(props.goal.name) @@ -43,6 +45,7 @@ export function GoalManager(props: Props) { const updatedGoal: Goal = { ...props.goal, name: nextName, + icon: emoji, } dispatch(updateGoalRedux(updatedGoal)) updateGoalApi(props.goal.id, updatedGoal) @@ -56,6 +59,7 @@ export function GoalManager(props: Props) { name: name ?? props.goal.name, targetDate: targetDate ?? props.goal.targetDate, targetAmount: nextTargetAmount, + icon: emoji, } dispatch(updateGoalRedux(updatedGoal)) updateGoalApi(props.goal.id, updatedGoal) @@ -69,6 +73,7 @@ export function GoalManager(props: Props) { name: name ?? props.goal.name, targetDate: date ?? props.goal.targetDate, targetAmount: targetAmount ?? props.goal.targetAmount, + icon: emoji, } dispatch(updateGoalRedux(updatedGoal)) updateGoalApi(props.goal.id, updatedGoal) @@ -106,6 +111,13 @@ export function GoalManager(props: Props) { {new Date(props.goal.created).toLocaleDateString()} + + + + + setEmoji(e.native)} /> + + ) } diff --git a/src/ui/pages/Main/goals/GoalCard.tsx b/src/ui/pages/Main/goals/GoalCard.tsx index e8f6d0a..01fc0ed 100644 --- a/src/ui/pages/Main/goals/GoalCard.tsx +++ b/src/ui/pages/Main/goals/GoalCard.tsx @@ -15,6 +15,7 @@ export default function GoalCard(props: Props) { const dispatch = useAppDispatch() const goal = useAppSelector(selectGoalsMap)[props.id] + console.log(goal) const onClick = (event: React.MouseEvent) => { event.stopPropagation() @@ -27,6 +28,9 @@ export default function GoalCard(props: Props) { return ( + + {goal?.icon ?? "🎯"} + ${goal.targetAmount} {asLocaleDateString(goal.targetDate)} diff --git a/tsconfig.json b/tsconfig.json index a273b0c..331fee0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es5", + "target": "es2017", "lib": [ "dom", "dom.iterable", From 42d5a5d6bf84bf312b9151bbeb8093e48a1e31eb Mon Sep 17 00:00:00 2001 From: Garima Meena Date: Sat, 27 Jun 2026 15:45:39 +0530 Subject: [PATCH 2/3] support icons --- .../public}/favicon/android-chrome-192x192.png | Bin .../public}/favicon/android-chrome-512x512.png | Bin {public => src/public}/favicon/apple-touch-icon.png | Bin {public => src/public}/favicon/browserconfig.xml | 0 {public => src/public}/favicon/favicon-16x16.png | Bin {public => src/public}/favicon/favicon-32x32.png | Bin {public => src/public}/favicon/favicon.ico | Bin {public => src/public}/favicon/mstile-144x144.png | Bin {public => src/public}/favicon/mstile-150x150.png | Bin {public => src/public}/favicon/mstile-310x150.png | Bin {public => src/public}/favicon/mstile-310x310.png | Bin {public => src/public}/favicon/mstile-70x70.png | Bin {public => src/public}/favicon/site.webmanifest | 0 {public => src/public}/index.html | 0 14 files changed, 0 insertions(+), 0 deletions(-) rename {public => src/public}/favicon/android-chrome-192x192.png (100%) rename {public => src/public}/favicon/android-chrome-512x512.png (100%) rename {public => src/public}/favicon/apple-touch-icon.png (100%) rename {public => src/public}/favicon/browserconfig.xml (100%) rename {public => src/public}/favicon/favicon-16x16.png (100%) rename {public => src/public}/favicon/favicon-32x32.png (100%) rename {public => src/public}/favicon/favicon.ico (100%) rename {public => src/public}/favicon/mstile-144x144.png (100%) rename {public => src/public}/favicon/mstile-150x150.png (100%) rename {public => src/public}/favicon/mstile-310x150.png (100%) rename {public => src/public}/favicon/mstile-310x310.png (100%) rename {public => src/public}/favicon/mstile-70x70.png (100%) rename {public => src/public}/favicon/site.webmanifest (100%) rename {public => src/public}/index.html (100%) diff --git a/public/favicon/android-chrome-192x192.png b/src/public/favicon/android-chrome-192x192.png similarity index 100% rename from public/favicon/android-chrome-192x192.png rename to src/public/favicon/android-chrome-192x192.png diff --git a/public/favicon/android-chrome-512x512.png b/src/public/favicon/android-chrome-512x512.png similarity index 100% rename from public/favicon/android-chrome-512x512.png rename to src/public/favicon/android-chrome-512x512.png diff --git a/public/favicon/apple-touch-icon.png b/src/public/favicon/apple-touch-icon.png similarity index 100% rename from public/favicon/apple-touch-icon.png rename to src/public/favicon/apple-touch-icon.png diff --git a/public/favicon/browserconfig.xml b/src/public/favicon/browserconfig.xml similarity index 100% rename from public/favicon/browserconfig.xml rename to src/public/favicon/browserconfig.xml diff --git a/public/favicon/favicon-16x16.png b/src/public/favicon/favicon-16x16.png similarity index 100% rename from public/favicon/favicon-16x16.png rename to src/public/favicon/favicon-16x16.png diff --git a/public/favicon/favicon-32x32.png b/src/public/favicon/favicon-32x32.png similarity index 100% rename from public/favicon/favicon-32x32.png rename to src/public/favicon/favicon-32x32.png diff --git a/public/favicon/favicon.ico b/src/public/favicon/favicon.ico similarity index 100% rename from public/favicon/favicon.ico rename to src/public/favicon/favicon.ico diff --git a/public/favicon/mstile-144x144.png b/src/public/favicon/mstile-144x144.png similarity index 100% rename from public/favicon/mstile-144x144.png rename to src/public/favicon/mstile-144x144.png diff --git a/public/favicon/mstile-150x150.png b/src/public/favicon/mstile-150x150.png similarity index 100% rename from public/favicon/mstile-150x150.png rename to src/public/favicon/mstile-150x150.png diff --git a/public/favicon/mstile-310x150.png b/src/public/favicon/mstile-310x150.png similarity index 100% rename from public/favicon/mstile-310x150.png rename to src/public/favicon/mstile-310x150.png diff --git a/public/favicon/mstile-310x310.png b/src/public/favicon/mstile-310x310.png similarity index 100% rename from public/favicon/mstile-310x310.png rename to src/public/favicon/mstile-310x310.png diff --git a/public/favicon/mstile-70x70.png b/src/public/favicon/mstile-70x70.png similarity index 100% rename from public/favicon/mstile-70x70.png rename to src/public/favicon/mstile-70x70.png diff --git a/public/favicon/site.webmanifest b/src/public/favicon/site.webmanifest similarity index 100% rename from public/favicon/site.webmanifest rename to src/public/favicon/site.webmanifest diff --git a/public/index.html b/src/public/index.html similarity index 100% rename from public/index.html rename to src/public/index.html From 849bce51492d8afe841cdca0f786f1a95e1038a6 Mon Sep 17 00:00:00 2001 From: Garima Meena Date: Sat, 27 Jun 2026 22:07:57 +0530 Subject: [PATCH 3/3] Task 5 changes added --- .../favicon/android-chrome-192x192.png | Bin .../favicon/android-chrome-512x512.png | Bin .../favicon/apple-touch-icon.png | Bin .../favicon/browserconfig.xml | 0 .../favicon/favicon-16x16.png | Bin .../favicon/favicon-32x32.png | Bin {src/public => public}/favicon/favicon.ico | Bin .../favicon/mstile-144x144.png | Bin .../favicon/mstile-150x150.png | Bin .../favicon/mstile-310x150.png | Bin .../favicon/mstile-310x310.png | Bin .../favicon/mstile-70x70.png | Bin .../favicon/site.webmanifest | 0 {src/public => public}/index.html | 0 src/ui/features/goalmanager/GoalManager.tsx | 18 ++++++++- .../pages/Main/goals/GoalControllerTests.cs | 38 ++++++++++++++++++ 16 files changed, 55 insertions(+), 1 deletion(-) rename {src/public => public}/favicon/android-chrome-192x192.png (100%) rename {src/public => public}/favicon/android-chrome-512x512.png (100%) rename {src/public => public}/favicon/apple-touch-icon.png (100%) rename {src/public => public}/favicon/browserconfig.xml (100%) rename {src/public => public}/favicon/favicon-16x16.png (100%) rename {src/public => public}/favicon/favicon-32x32.png (100%) rename {src/public => public}/favicon/favicon.ico (100%) rename {src/public => public}/favicon/mstile-144x144.png (100%) rename {src/public => public}/favicon/mstile-150x150.png (100%) rename {src/public => public}/favicon/mstile-310x150.png (100%) rename {src/public => public}/favicon/mstile-310x310.png (100%) rename {src/public => public}/favicon/mstile-70x70.png (100%) rename {src/public => public}/favicon/site.webmanifest (100%) rename {src/public => public}/index.html (100%) create mode 100644 src/ui/pages/Main/goals/GoalControllerTests.cs diff --git a/src/public/favicon/android-chrome-192x192.png b/public/favicon/android-chrome-192x192.png similarity index 100% rename from src/public/favicon/android-chrome-192x192.png rename to public/favicon/android-chrome-192x192.png diff --git a/src/public/favicon/android-chrome-512x512.png b/public/favicon/android-chrome-512x512.png similarity index 100% rename from src/public/favicon/android-chrome-512x512.png rename to public/favicon/android-chrome-512x512.png diff --git a/src/public/favicon/apple-touch-icon.png b/public/favicon/apple-touch-icon.png similarity index 100% rename from src/public/favicon/apple-touch-icon.png rename to public/favicon/apple-touch-icon.png diff --git a/src/public/favicon/browserconfig.xml b/public/favicon/browserconfig.xml similarity index 100% rename from src/public/favicon/browserconfig.xml rename to public/favicon/browserconfig.xml diff --git a/src/public/favicon/favicon-16x16.png b/public/favicon/favicon-16x16.png similarity index 100% rename from src/public/favicon/favicon-16x16.png rename to public/favicon/favicon-16x16.png diff --git a/src/public/favicon/favicon-32x32.png b/public/favicon/favicon-32x32.png similarity index 100% rename from src/public/favicon/favicon-32x32.png rename to public/favicon/favicon-32x32.png diff --git a/src/public/favicon/favicon.ico b/public/favicon/favicon.ico similarity index 100% rename from src/public/favicon/favicon.ico rename to public/favicon/favicon.ico diff --git a/src/public/favicon/mstile-144x144.png b/public/favicon/mstile-144x144.png similarity index 100% rename from src/public/favicon/mstile-144x144.png rename to public/favicon/mstile-144x144.png diff --git a/src/public/favicon/mstile-150x150.png b/public/favicon/mstile-150x150.png similarity index 100% rename from src/public/favicon/mstile-150x150.png rename to public/favicon/mstile-150x150.png diff --git a/src/public/favicon/mstile-310x150.png b/public/favicon/mstile-310x150.png similarity index 100% rename from src/public/favicon/mstile-310x150.png rename to public/favicon/mstile-310x150.png diff --git a/src/public/favicon/mstile-310x310.png b/public/favicon/mstile-310x310.png similarity index 100% rename from src/public/favicon/mstile-310x310.png rename to public/favicon/mstile-310x310.png diff --git a/src/public/favicon/mstile-70x70.png b/public/favicon/mstile-70x70.png similarity index 100% rename from src/public/favicon/mstile-70x70.png rename to public/favicon/mstile-70x70.png diff --git a/src/public/favicon/site.webmanifest b/public/favicon/site.webmanifest similarity index 100% rename from src/public/favicon/site.webmanifest rename to public/favicon/site.webmanifest diff --git a/src/public/index.html b/public/index.html similarity index 100% rename from src/public/index.html rename to public/index.html diff --git a/src/ui/features/goalmanager/GoalManager.tsx b/src/ui/features/goalmanager/GoalManager.tsx index 634efc5..60d8ca4 100644 --- a/src/ui/features/goalmanager/GoalManager.tsx +++ b/src/ui/features/goalmanager/GoalManager.tsx @@ -79,6 +79,22 @@ export function GoalManager(props: Props) { updateGoalApi(props.goal.id, updatedGoal) } } + const pickEmojiOnClick = async (e: any) => { + const selectedEmoji = e.native + + setEmoji(selectedEmoji) + + const updatedGoal: Goal = { + ...props.goal, + icon: selectedEmoji, + name: name ?? props.goal.name, + targetDate: targetDate ?? props.goal.targetDate, + targetAmount: targetAmount ?? props.goal.targetAmount, + } + + dispatch(updateGoalRedux(updatedGoal)) + await updateGoalApi(props.goal.id, updatedGoal) +} return ( @@ -115,7 +131,7 @@ export function GoalManager(props: Props) { - setEmoji(e.native)} /> + diff --git a/src/ui/pages/Main/goals/GoalControllerTests.cs b/src/ui/pages/Main/goals/GoalControllerTests.cs new file mode 100644 index 0000000..e7a5d89 --- /dev/null +++ b/src/ui/pages/Main/goals/GoalControllerTests.cs @@ -0,0 +1,38 @@ +using Xunit; + +public class GoalControllerTests +{ + private readonly FakeCollections collections; + + public GoalControllerTests() + { + collections = new(); + } + + [Fact] + public async void GetForUser() + { + // Arrange + var goals = collections.GetGoals(); + var users = collections.GetUsers(); + IGoalsService goalsService = new FakeGoalsService(goals, goals[0]); + IUsersService usersService = new FakeUsersService(users, users[0]); + GoalController controller = new(goalsService, usersService); + + // Act + var httpContext = new Microsoft.AspNetCore.Http.DefaultHttpContext(); + controller.ControllerContext.HttpContext = httpContext; + var result = await controller.GetForUser(goals[0].UserId!); + + // Assert + Assert.NotNull(result); + + var index = 0; + foreach (Goal goal in result!) + { + Assert.IsAssignableFrom(goal); + Assert.Equal(goals[0].UserId, goal.UserId); + index++; + } + } +} \ No newline at end of file