feat: add restriction to prevent deletion of system tasks and rewards
All checks were successful
Gitea Actions Demo / build-and-push (push) Successful in 23s
All checks were successful
Gitea Actions Demo / build-and-push (push) Successful in 23s
- Implemented logic to hide delete button for system tasks and rewards in ItemList.vue, TaskView.vue, and RewardView.vue. - Added backend checks in task_api.py and reward_api.py to return 403 for delete requests on system items. - Ensured that items without a user_id are treated as system items across frontend and backend. - Updated acceptance criteria to include UI and backend tests for the new functionality.
This commit is contained in:
63
.github/specs/active/profile-button-menu/feat-profile-icon-button-menu.md
vendored
Normal file
63
.github/specs/active/profile-button-menu/feat-profile-icon-button-menu.md
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
# Feature: Replace the text-based "Parent" button with an image icon and modernize the dropdown menu
|
||||
|
||||
## Visual Reference:
|
||||
|
||||
- **Sample Design:** #mockup.png
|
||||
- **Design:**
|
||||
1. Dropdown header colors need to match color theme inside #colors.css
|
||||
2. The three dropdown items should be "Profile", "Child Mode", and "Sign out"
|
||||
3. Currently, the dropdown shows "Log out" for "Child Mode", that should be changed to "Child Mode"
|
||||
|
||||
## Context:
|
||||
|
||||
- **Goal:** I want a user image icon to display in place of the current "Parent" button
|
||||
- **User Story:** As a [user], I want to see the image assigned in my profile as an icon button at the top right of the screen. When I click the button I want to see a dropdown appear if I'm in 'parent mode.' I to have the options to see/edit my profile, go back to child mode, or sign out. In child mode, I want the button to trigger the parent pin modal if clicked.
|
||||
|
||||
## Technical Requirements
|
||||
|
||||
- **File Affected:** LoginButton.vue, ParentLayout.vue, ChildLayout.vue, AuthLayout.vue
|
||||
- **Navigation:**
|
||||
1. When the avatar button is focused, pressing Enter or Space opens the dropdown.
|
||||
2. When the dropdown is open:
|
||||
- Up/Down arrow keys move focus between menu items.
|
||||
- Enter or Space activates the focused menu item.
|
||||
- Esc closes the dropdown and returns focus to the avatar button.
|
||||
3. Tabbing away from the dropdown closes it.
|
||||
- **ARIA:**
|
||||
1. The avatar button must have aria-haspopup="menu" and aria-expanded reflecting the dropdown state.
|
||||
2. The dropdown menu must use role="menu", and each item must use role="menuitem".
|
||||
3. The currently focused menu item should have aria-selected="true".
|
||||
- **Focus Ring:** All interactive elements (avatar button and dropdown menu items) must display a visible focus ring when focused via keyboard navigation. The focus ring color should use a theme variable from colors.css and meet accessibility contrast guidelines.
|
||||
- **Mobile & Layout:**
|
||||
1. The avatar icon button must always be positioned at the top right of the screen, regardless of device size.
|
||||
2. The icon must never exceed 65px in width or height.
|
||||
3. On mobile, ensure the button is at least 44x44px for touch accessibility.
|
||||
- **Avatar Fallback:** If user.first_name does not exist, display a ? as the fallback initial.
|
||||
- **Dropdown Placement and Animation:**
|
||||
1. The dropdown menu must always appear directly below the avatar icon, right-aligned to the screen edge.
|
||||
2. Use a slide down/up animation for showing/hiding the dropdown.
|
||||
- **State Requirements:**
|
||||
- Collapsed: Button shows the user.image_id or a fallback icon with the initial of the user.first_name
|
||||
- Expanded: Shows the dropdown with the three menu options shown in the #mockup.png. -**Menu Item Icons:**: For now, use a stub element or placeholder for each menu item icon, to be replaced with real icons later.
|
||||
- **Logic:**
|
||||
1. Clicking an item in the dropdown should already be implemented. Do not change this.
|
||||
2. When clicking a menu item or clicking outside the menu, collapse the menu.
|
||||
3. When in 'child mode' (parent not authenticated), show the parent PIN modal or create PIN view (/parent/pin-setup) if user.pin doesn't exist or is empty. (this is already implemented)
|
||||
|
||||
## UI Acceptance Criteria (The "Definition of Done")
|
||||
|
||||
- [ ] UI: Swap the "Parent" button with the user's avatar image.
|
||||
- [ ] UI: Refactor #LoginButton.vue to use new CSS generated from #mockup.png
|
||||
- [ ] Logic: Make sure the dropdown does not show when in child mode.
|
||||
- [ ] Logic: Make sure the parent PIN modal shows when the button is pressed in child mode.
|
||||
- [ ] Logic: Make sure the parent PIN creation view shows when the button is pressed in child mode if no user.pin doesn't exist or is empty.
|
||||
- [ ] Frontend Tests: Add vitest for this feature in the frontend to make sure the logic for button clicking in parent mode and child mode act correctly.
|
||||
1. [ ] Avatar button renders image, initial, or ? as fallback
|
||||
2. [ ] Dropdown opens/closes via click, Enter, Space, Esc, and outside click.
|
||||
3. [ ] Dropdown is positioned and animated correctly.
|
||||
4. [ ] Keyboard navigation (Up/Down, Enter, Space, Esc) works as specified.
|
||||
5. [ ] ARIA attributes and roles are set correctly.
|
||||
6. [ ] Focus ring is visible and uses theme color.
|
||||
7. [ ] Avatar button meets size and position requirements on all devices.
|
||||
8. [ ] Menu logic for parent/child mode is correct.
|
||||
9. [ ] Stub icons are rendered for menu items.
|
||||
BIN
.github/specs/active/profile-button-menu/mockup.png
vendored
Normal file
BIN
.github/specs/active/profile-button-menu/mockup.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
@@ -119,5 +119,6 @@ const showBack = computed(
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
overflow-y: visible;
|
||||
padding: 1rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -118,5 +118,6 @@ const showBack = computed(() => route.path !== '/child')
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
overflow-y: visible;
|
||||
padding: 1rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -292,6 +292,7 @@ onMounted(async () => {
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
overflow-y: visible;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.app-version {
|
||||
|
||||
Reference in New Issue
Block a user