Skip to content

Mobile tasks#132

Merged
spokonya merged 20 commits intomainfrom
mobile-tasks
Mar 17, 2026
Merged

Mobile tasks#132
spokonya merged 20 commits intomainfrom
mobile-tasks

Conversation

@spokonya
Copy link
Copy Markdown
Contributor

@spokonya spokonya commented Feb 18, 2026

Description

Adds the Tasks page UI to the staff mobile app with two sub-tabs: My Tasks (assigned) and Unassigned Tasks. Task cards display priority, location, department, and description with expanded and compact layouts depending on assignment status. All data is hardcoded

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactoring (code improvement without changing functionality)
  • Documentation update
  • Configuration/infrastructure change
  • Performance improvement
  • Test coverage improvement

Related Issue(s)

Closes #103
Related to #

What Changed?

-Add Tasks tab screen with My Tasks / Unassigned Tasks sub-tabs displaying hardcoded task data
-Build task card components with expanded (Start/Claim Task button) and compact (badge + three-dot menu) variants
-Register Tasks tab in bottom navigator with checklist icon

Testing & Validation

How this was tested

Screenshots/Recordings

IMG_6752 IMG_6751

Unfinished Work & Known Issues

  • None, this PR is complete and production-ready
  • The following items are intentionally deferred:



Notes & Nuances



Pre-Merge Checklist

Code Quality

  • [] Code follows the project's style guidelines and conventions
  • Self-review completed (I've reviewed my own code for obvious issues)
  • No debugging code, console logs, or commented-out code left behind
  • No merge conflicts with the base branch
  • Meaningful commit messages that explain the "why"

Testing & CI

  • [] All CI checks are passing
  • [] All new and existing tests pass locally
  • [] Test coverage hasn't decreased (or decrease is justified)
  • [] Linting passes without errors

Documentation

  • Code is self-documenting or includes helpful comments for complex logic
  • API documentation updated (if backend endpoints changed)
  • Type definitions are accurate and up-to-date

Reviewer Notes

  • Areas needing extra attention: ...
  • Questions for reviewers: ...

Copy link
Copy Markdown
Contributor

@Dao-Ho Dao-Ho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments / things to consider for next time. I think this is good to ship for the most part, for the ones I stated we can forego, no need to make those changes. Overall great ship! 🔥

Comment thread clients/mobile/app/(tabs)/tasks.tsx Outdated
import { myTasks, unassignedTasks } from "@/data/mockTasks";

export default function TasksScreen() {
const [activeTab, setActiveTab] = useState<"myTasks" | "unassigned">("myTasks");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd make these constant/enum (MY_TASKS & UNASSIGNED) just make sure there's no potential of mispelling

Comment thread clients/mobile/app/(tabs)/tasks.tsx Outdated
<View className="flex-1">
<TaskList
tasks={activeTab === "myTasks" ? myTasks : unassignedTasks}
variant={activeTab === "myTasks" ? "assigned" : "unassigned"}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a ternary operator here really boxes you in to only two choices. What if we wanted to add another tab in the future (say, "overdue")?

I would actually define this data before passing the prop.
Something like would allow you to easily extend upon this code when we go and add in a new tab

const tabConfigs = {
  myTasks: { tasks: myTasks, variant: "assigned", showFilters: false },
  unassigned: { tasks: unassignedTasks, variant: "unassigned", showFilters: true },
};

const currentTabConfig = tabConfigs[activeTab];
...
<TaskList tasks={currentTabConfig.tasks} variant={currentTabConfig.variant} />

export function ActiveFilterChips({
filters,
onRemoveFilter = () => {},
onClearAll = () => {},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't allow a default no-op here, we should enforce that these are passed into the component. We don't want any unexpected cases where the caller only passes the filters and questions why the remove functionality isn't working

import MaterialCommunityIcons from "@expo/vector-icons/MaterialCommunityIcons";
import { Pressable, Text, View } from "react-native";

type TabId = "myTasks" | "unassigned";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good place for the constant/enum mentioned above

}

export function TaskCard({ task, variant, isExpanded }: TaskCardProps) {
const isAssigned = variant === "assigned";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use const/enum


interface TaskCardProps {
task: Task;
variant: "assigned" | "unassigned";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use const/enum

export function TaskList({ tasks, variant }: TaskListProps) {
const renderItem: ListRenderItem<Task> = ({ item, index }) => {
const isExpanded =
variant === "assigned" ? index === 0 : item.priority === "High";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use const/enum for variant (no need for priority for now)

<Feather name="sliders" size={24} color="#000" />
</Pressable>
<Pressable onPress={() => {}}>
<Feather name="bell" size={24} color="#000" />
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok for now, but some things to consider about:

What if we wanted to update the styling of Feather? We'd need to make sure we remember to update it in all use cases of this. No need to do this for now but you should abstract and make it a separate component whenever you see a case like this

dueTime?: string;
isAssigned: boolean;
}

Copy link
Copy Markdown
Contributor

@Dao-Ho Dao-Ho Feb 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is ok for now since it's mock data but for types, I'd keep this in a separate file in the future

a /types seems appropriate to store this

Copy link
Copy Markdown
Contributor

@Dao-Ho Dao-Ho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment

Comment thread clients/mobile/constants/tasks.ts Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (main@b183995). Learn more about missing BASE report.

Additional details and impacted files

Impacted file tree graph

@@          Coverage Diff           @@
##             main    #132   +/-   ##
======================================
  Coverage        ?   4.03%           
======================================
  Files           ?      45           
  Lines           ?    1337           
  Branches        ?      24           
======================================
  Hits            ?      54           
  Misses          ?    1283           
  Partials        ?       0           
Flag Coverage Δ
mobile 84.00% <ø> (?)
web 0.93% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@Dao-Ho Dao-Ho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🚀

@spokonya spokonya merged commit 61c284c into main Mar 17, 2026
16 checks passed
@spokonya spokonya deleted the mobile-tasks branch March 17, 2026 20:57
Dao-Ho added a commit that referenced this pull request Mar 18, 2026
* Mobile tasks (#132)

* add mock task data and Task type definition

* add TaskBadge and TasksHeader components

* add TabBar and ActiveFilterChips components

* add TaskCard and TaskList components

* added tasks tab screen and register in tab navigator

* fix babel.config

* icon

* Refactor activeTab state to use TabName type

* Refactor task handling with tabConfigs

* Refactor ActiveFilterChipsProps to enforce required props

Updated ActiveFilterChipsProps to require onRemoveFilter and onClearAll callbacks.

* Refactor tab identifiers to use constants

* made constant file with VARIANT and TAB and replaced string literals

* packagelock.json

* attempting to update package and package lock

* attempt 2

* attempt 3

* VARIENT name change

* ran npx prettier --write

---------

Co-authored-by: Dao Ho <84757503+Dao-Ho@users.noreply.github.com>

* Feat/guest and booking endpoint (#178)

* rooms migration file

* feat: guest booking migration

* rls fix

* indexes on both tables

* type fix

* incomplete guest bookings table + endpoint

* server integrated + openapi

* moved getRooms to rooms repo

* get guests endpoint

* changes

* fixed openapi

* remove stale webhook dir

* route for specific guest info

* cleanup GetBookingsByFloor handler

* changed some models

* filtered by hotel id

* lint

* may the lint gods be merciful

* comments

* fixed issue

* rename

---------

Co-authored-by: eric-kitagawa <kitagawa.e@northeastern.edu>

* migration 1 -> add request_version column and drop updated_at column (#188)

* migration file 2, instead of request_id primary key -> (request_id, request_version) composite key (#190)

* guest info added (#182)

* feat: reveal rooms page in dashboard + updated some styling (#192)

* reveal rooms page in dashboard

* updated selected styling + tags styling

* update side panel buttons to use primary color as well

* format

* lint

---------

Co-authored-by: Ari Spokony <spokonya@outlook.com>
Co-authored-by: Manuel Torres <torres.man@northeastern.edu>
Co-authored-by: eric-kitagawa <kitagawa.e@northeastern.edu>
Co-authored-by: Tyler Kim <tdk737@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: lofi for rooms page mobile

2 participants