1. Overview
The Schedule Listing module provides a comprehensive interface for users to view, filter, and interact with scheduled audits in the Nimbly 2.0 application. This module serves as a central hub for audit management, allowing users to track completion rates, switch between daily and period views, and manage both individual and [team audits](../Team Audit/TeamAuditOverview.md).
2. Architecture
The Schedule Listing module follows a component-based architecture with clear separation of concerns. The architecture is built around the following principles:
- Component Isolation: Each component handles a specific responsibility
- Controller Pattern: Business logic is separated into controller hooks
- Query-Based Data Fetching: React Query is used for efficient data fetching and caching
- Parameter-based Routing: URL parameters control view state for shareable views
flowchart TD A[ScheduleHomeScreen] --> B[ScheduleCompletionRate] A --> C[ScheduleTabs] A --> D[ScheduleCalendar] A --> E[ScheduleList] A --> F[ScheduleStartReport] A --> G[TeamReportStartBottomSheet] C --> H[Daily Tab] C --> I[Active Period Tab] E --> J[ViewByController] J --> K[Status Cards] J --> L[Location Cards] J --> M[Schedule Type Cards] E --> N[ScheduleItems] N --> O[SingleAuditItem] N --> P[TeamAuditItem] D --> Q[CalendarController] Q --> R[DateParamController] F --> S[ScheduleStartReportController] S --> T[StartReportMutation] G --> U[TeamReportStartController] U --> V[StartTeamReportMutation]
3. Core Components
3.1 ScheduleHomeScreen
The main entry point for the schedule interface, coordinating all sub-components. This component serves as the container for all schedule-related functionality.
Source: screen.tsx
export default function ScheduleHomeScreen() {
const { activeTab } = useScheduleTabController();
const navBottomHeight = useAtomValue(navBottomHeightAtom);
return (
<>
<YStack flex={1} marginBottom={navBottomHeight}>
<ScheduleCompletionRate />
<ScheduleTabs />
{activeTab === ScheduleTabType.DAILY ? <ScheduleCalendar /> : null}
<ScheduleList />
</YStack>
<ScheduleStartReport />
<TeamReportStartBottomSheet />
</>
);
}3.2 ScheduleCompletionRate
Displays the current completion rate for scheduled audits in the active period. This component visualizes progress with a circular progress indicator and percentage display.
Source: completition-rate/index.tsx
The component fetches data using useScheduleProgressQuery which calculates:
- Total audits scheduled for the period
- Number of completed audits
- Percentage completion
- Visual indicators when targets are met
3.3 ScheduleTabs
Provides tab navigation between daily and active period views, allowing users to switch context quickly.
Source: active-period/index.tsx
flowchart LR A[ScheduleTabs] --> B[Daily Tab] A --> C[Active Period Tab] B --> D[Calendar View] C --> E[Period View] B -- "Updates URL params" --> F[date parameter] C -- "Updates URL params" --> G[activeTab parameter]
The tabs utilize the useScheduleTabController to manage tab state:
export const useScheduleTabController = () => {
const [activeTab, setActiveTab] = useScheduleParam("activeTab", {
initial: ScheduleTabType.DAILY,
parse: (value) => {
// Parse and validate tab type
return isValidScheduleTabType(value) ? value : ScheduleTabType.DAILY;
},
});
return {
activeTab,
setActiveTab,
isDailyTab: activeTab === ScheduleTabType.DAILY,
isActivePeriodTab: activeTab === ScheduleTabType.ACTIVE_PERIOD,
};
};3.4 ScheduleCalendar
Provides date selection for filtering schedules in daily view. The calendar displays dates with scheduled audits and their statuses using color-coded indicators.
Source: calendar/index.tsx
4. Data Flow
The schedule listing data flow follows this pattern:
sequenceDiagram participant User participant UI Components participant URL Parameters participant Controllers participant React Query participant API Client participant Backend API User->>UI Components: Select view mode/filter UI Components->>URL Parameters: Update parameters URL Parameters->>Controllers: Parameter change triggers controller Controllers->>React Query: Query with updated parameters React Query->>API Client: Make API request if needed API Client->>Backend API: Send request Backend API->>API Client: Return results API Client->>React Query: Cache results React Query->>Controllers: Return data or loading state Controllers->>UI Components: Update with processed data UI Components->>User: Display updated view
4.1 Parameter-Based Controllers
The schedule module uses a parameter-based system to control views through URL parameters, making states shareable via URLs.
4.1.1 Param Controller
The foundation for all parameter-based state management in the schedule module.
Source: params-controller.ts
export const useScheduleParam = <T>(
key: string,
options: ParamOptions<T> = {}
): [T | undefined, (value: T | undefined) => void] => {
// Implementation handles parameter parsing, validation, and updates
// Syncs state with URL parameters for shareable views
// ...
};4.1.2 View By Controller
Controls the grouping and filtering mode for schedules.
Source: view-by-controller.ts
export const useViewByController = () => {
const [viewBy, setViewBy] = useScheduleParam("viewBy", {
initial: "none",
parse: (templateFromUrl) => {
if (templateFromUrl && typeof templateFromUrl === "string") {
return templateFromUrl;
}
return "day";
},
});
return {
setViewBy,
viewBy: (viewBy ?? "none") as ViewBy,
};
};4.1.3 Date Parameter Controller
Manages the selected date for daily schedule views.
Source: date-param-controller.ts
5. Schedule Parameters System
A key architectural feature of the Schedule Listing module is its parameter-based system, which enables:
- Shareable States: All view states can be shared via URLs
- Persistent Navigation: State persists through app navigation
- Deep Linking: External links can open specific schedule views
- History Management: Browser history integration for navigation
5.1 Parameter Types
flowchart TD A[Schedule Parameters] --> B[Date Parameter] A --> C[ViewBy Parameter] A --> D[ActiveTab Parameter] A --> E[StatusFilter Parameter] A --> F[LocationFilter Parameter] A --> G[TypeFilter Parameter] B -- Controls --> H[Calendar Date Selection] C -- Controls --> I[Grouping Mode] D -- Controls --> J[Tab Selection] E -- Controls --> K[Status Filtering] F -- Controls --> L[Location Filtering] G -- Controls --> M[Schedule Type Filtering]
5.2 Parameter Flow
sequenceDiagram participant User participant Component participant ParamController participant URL participant QueryString User->>Component: Change view setting Component->>ParamController: Update parameter ParamController->>QueryString: Parse & validate QueryString->>URL: Update query parameters URL-->>User: URL updated (shareable state) Note over ParamController,URL: On page load/refresh URL->>QueryString: Read parameters QueryString->>ParamController: Parse parameters ParamController->>Component: Initialize with URL state
6. View Modes
6.1 Daily View
Shows schedules for a specific day with calendar selection. This view is focused on what audits need to be completed on a particular day.
flowchart TD A[Calendar Selection] --> B[Date Parameter] B --> C[Filtered Schedule Query] C --> D[Schedule Items] D --> E[Audit Actions]
Implementation Details:
- Uses
useDateParamControllerto track selected date - Updates URL with date parameter for shareable views
- Filters schedule data through
useScheduleQuerywith date parameter - Renders schedule items specific to selected date
6.2 Active Period View
Shows all active schedules for the current period defined by organization settings. This view provides a broader perspective on the audit workload for the entire period.
flowchart TD A[Organization Period Settings] --> B[Period Calculation] B --> C[Active Schedule Query] C --> D[Schedule Items] D --> E[Period Statistics] E --> F[Completion Rates]
Implementation Details:
- Uses organization settings to determine current period
- Fetches all schedules within the active period
- Groups and sorts schedules based on user preference
- Shows completion statistics for the period
7. Filtering System
The schedule listing implements a flexible filtering system with multiple view options:
7.1 View By Selector
Allows users to group and filter schedules by status, location, or schedule type.
Source: view-by-selector/index.tsx
export default function ScheduleViewBy() {
const { LL } = useLocalization();
const { setViewBy, viewBy } = useViewByController();
// ...options setup
return (
<XStack px="$tw4" py="$tw1" alignItems="center" gap="$tw2">
<Text caption>{LL.schedule.schedule.viewBy()}</Text>
<ScrollView horizontal>
<XStack gap="$tw2" flexWrap="wrap">
{options.map(({ key, label }) => (
<Chip
key={key}
onPress={runWithConnectivityCheck(() => setViewBy(key))}
active={viewBy === key}
>
{LL.schedule.filter.viewBy[label]()}
</Chip>
))}
</XStack>
</ScrollView>
</XStack>
);
}7.2 Filter Logic Flow
sequenceDiagram participant User participant ViewSelector participant ViewByController participant ScheduleQuery participant FilterProcessor participant ScheduleList User->>ViewSelector: Select filter mode ViewSelector->>ViewByController: Update viewBy parameter ViewByController->>ScheduleQuery: Query with viewBy parameter ScheduleQuery->>FilterProcessor: Process data with filter FilterProcessor-->>ScheduleList: Return filtered/grouped data ScheduleList-->>User: Display filtered view
7.3 Filter Types
7.3.1 Status Filter
Groups schedules by their completion status.
Source: status-card/list.tsx
flowchart LR A[Status Filter] --> B[Completed] A --> C[In-Progress] A --> D[Missed] A --> E[Not Started] A --> F[Overdue]
Implementation Details:
- Calculates schedule status based on completion, due date, and current time
- Groups schedules by status categories
- Provides counts and visual indicators for each status group
- Allows filtering to show only schedules of a specific status
7.3.2 Location Filter
Groups schedules by their assigned location.
Source: location-card/list.tsx
flowchart LR A[Location Filter] --> B[Location 1] A --> C[Location 2] A --> D[Location ...] A --> E[Location N]
Implementation Details:
- Fetches and displays all locations with scheduled audits
- Shows the count of scheduled audits per location
- Filters schedules to show only those at a selected location
- Updates URL parameters for shareable filtered views
7.3.3 Schedule Type Filter
Groups schedules by type (single audit vs team audit).
Source: schedule-type-card/list.tsx
flowchart LR A[Schedule Type Filter] --> B[Single Audit](../../Schedule/Single Audit/SingleAuditOverview.md) A --> C[Team Audit](../../Schedule/Team Audit/TeamAuditOverview.md)
Implementation Details:
- Categorizes schedules based on audit type (individual or team)
- Shows count and statistics for each audit type
- Filters displayed schedules by selected type
- Updates URL parameters for consistent navigation
8. Calendar Integration
The calendar component provides visual feedback on dates with scheduled audits using a powerful date management system.
flowchart TD A[Calendar Component] --> B[Date Selection] A --> C[Schedule Indicators] B --> D[DateParamController] D --> E[Filter by Date] C --> F[ScheduleIndicatorQuery] F --> G[Visual Markers]
8.1 Calendar Controller
Manages calendar state and configuration based on organization settings.
Source: calendar-controller.ts
export const useCalendarController = () => {
const [isVisible, setIsVisible] = useAtom(calendarVisibleAtom);
const [selectedDateParam, setSelectedDateParam] = useDateParamController();
// ...other functionality
return {
isVisible,
toggleIsVisible,
selectedDate,
selectDate,
calendarConfig,
markedDates: activeIndicator,
setVisibleDate,
};
};8.2 Schedule Indicators
The calendar visualizes dates with scheduled audits using color-coded indicators:
Source: schedule-indicator-query.ts
export const useScheduleIndicatorQuery = (params?: ScheduleIndicatorParams) => {
// Fetches schedule indicators for calendar visualization
// Returns color-coded indicators based on schedule status
};Indicator Logic:
- Blue: Has scheduled audits with no status issues
- Green: All scheduled audits are completed
- Yellow: Has in-progress audits
- Red: Contains missed or overdue audits
9. Data Fetching Strategy
The Schedule Listing module implements a sophisticated data fetching strategy using React Query to ensure optimal performance and user experience.
flowchart TD A[Data Needs] --> B{Cached?} B -- Yes --> C[Use Cached Data] B -- No --> D[Fetch from API] D --> E[Cache Results] E --> F[Update UI] C --> F G[Background Refetch] --> H{Has Changed?} H -- Yes --> I[Update Cache] I --> J[Update UI if Visible] H -- No --> K[Keep Current Data]
9.1 Query Implementation
Source: view-by-query.ts
export const useViewByDataQuery = () => {
const { viewBy } = useViewByController();
const params = useScheduleQueryParams();
// Different query based on view mode
switch (viewBy) {
case "status":
return useScheduleStatusQuery(params);
case "location":
return useScheduleLocationQuery(params);
case "type":
return useScheduleTypeQuery(params);
default:
return useScheduleDefaultQuery(params);
}
};9.2 Data Refetching
The module implements intelligent refetching strategies based on:
- User Navigation: Refetches when the user returns to the schedule screen
- Pull to Refresh: Manual refresh triggered by pull gesture
- Interval Updates: Background polling on configurable intervals
- Dependency Changes: Refetches when dependencies like date or filters change
Source: questionnaire-update-refetch-interval.ts
10. Status Visualization
Schedule statuses are visually represented with dedicated colors and icons to provide clear visual feedback on audit states.
Source: card/index.tsx
export enum CardBgColor {
BLUE = "#98CBF5",
YELLOW = "#FFD760",
GREEN = "#6BCBB7",
RED = "#FF8C8C",
PURPLE = "#A39DEE",
ORANGE = "#FFAE74",
LIGHT_GREEN = "#B5E2B3",
PINK = "#F7C8D6",
}10.1 Status Card Implementation
flowchart TD A[Status Card] --> B[Icon Based on Status] A --> C[Color Based on Status] A --> D[Count of Matching Schedules] A --> E[Localized Status Label] A --> F[Navigation to Filtered View]
Source: status-card/list.tsx
10.2 Status Calculation Logic
Source: schedule-status-utils.ts
export const getScheduleStatus = (schedule: Schedule): ScheduleStatus => {
const now = dayjs();
const dueDate = dayjs(schedule.dueDate);
if (schedule.completedAt) {
return "completed";
}
if (schedule.startedAt && !schedule.completedAt) {
return "in-progress";
}
if (dueDate.isBefore(now, "day")) {
return "missed";
}
if (dueDate.isSame(now, "day")) {
return "due-today";
}
return "not-started";
};11. Schedule Types
The application supports two primary schedule types with distinct workflows:
11.1 Single Audits
Individual audits performed by one user.
Source: single-audit.tsx
flowchart LR A[Single Audit](../../Schedule/Single Audit/SingleAuditOverview.md) --> B[Start Audit] B --> C[Complete Questions] C --> D[Submit Audit] D --> E[Review & Sign Off]
Implementation Details:
- Utilizes
ScheduleStartReportControllerto manage the audit start process - Tracks progress with
useAuditProgressQuery - Manages schedule state transitions (not started → in progress → completed)
- Provides resume functionality for in-progress audits
11.2 Team Audits
Collaborative audits performed by multiple team members.
Source: team-audit.tsx
flowchart LR A[Team Audit](../../Schedule/Team Audit/TeamAuditOverview.md) --> B[Initialize Team Session] B --> C[Assign Sections] C --> D[Collaborate on Questions] D --> E[Team Lead Review] E --> F[Submit Team Audit]
Implementation Details:
- Uses
TeamReportStartControllerto initialize team sessions - Tracks team member assignments and progress
- Shows real-time collaboration status when online
- Provides team lead with oversight capabilities
- Manages permissions based on user role
11.3 Schedule Type Cards
Source: schedule-type-card/list.tsx
const cardProperties: Record<
string,
{ color: CardBgColor; Icon: React.ReactElement }
> = {
single: {
Icon: <User />,
color: CardBgColor.PURPLE,
},
team: {
Icon: <Users />,
color: CardBgColor.GREEN,
},
};12. Offline Support
The application implements robust connectivity handling to manage offline states, ensuring usability even without an internet connection.
flowchart TD A[User Action] --> B{Has Connectivity?} B -->|Yes| C[Execute Online Action] B -->|No| D[Execute Offline Action] C --> E[Sync with Server] D --> F[Store in Offline Queue] F --> G{Connectivity Restored?} G -->|Yes| E G -->|No| F
12.1 Connectivity Controller
Source: connectivity-controller.ts
export const useConnectivity = () => {
const isOffline = useIsOffline();
const { showOfflineToast } = useOfflineToast();
const runWithConnectivityCheck = useCallback(
<T extends any[]>(callback: (...args: T) => void) =>
(...args: T) => {
if (isOffline) {
showOfflineToast();
return;
}
callback(...args);
},
[isOffline, showOfflineToast]
);
return { isOffline, runWithConnectivityCheck };
};12.2 Offline Queue System
The application implements an offline queue system that:
- Captures actions performed offline
- Stores them in persistent storage
- Attempts to replay them when connectivity is restored
- Handles conflict resolution for concurrent changes
Implementation Example:
// Wrapping actions that require connectivity
onPress: runWithConnectivityCheck(() => setViewBy(key));13. Performance Optimization
13.1 Virtual Lists
The application uses virtualized lists to optimize performance when rendering potentially large datasets:
Source: status-card/list.tsx
return (
<VirtualList
contentContainerStyle={styles.contentContainerStyle}
data={listData}
renderItem={({ item }) => <StatusCardListItem {...item} />}
numColumns={2}
estimatedItemSize={97}
refreshControl={
<RefreshControl refreshing={isFetching} onRefresh={refetch} />
}
/>
);13.2 Data Memoization
Components use React’s useMemo to avoid unnecessary calculations:
const listData = useMemo(() => {
if (!data) {
return [];
}
// Process data here
return processedData;
}, [data, dependencies]);13.3 Query Optimization
- Selective Fetching: Only fetches data needed for current view
- Data Pagination: Implements cursor-based pagination for large datasets
- Query Deduplication: Prevents duplicate network requests
- Stale-While-Revalidate: Shows cached data immediately while refreshing in background
- Prefetching: Anticipates user navigation and preloads likely needed data
Source: schedule-queries/index.ts
14. State Management
The Schedule Listing module uses Jotai for atomic state management, providing:
- Atomic Updates: Granular state updates minimize re-renders
- Computed State: Derived states update automatically
- Persistent State: Selected states persist in storage
- URL Synchronized State: Key states sync with URL parameters
14.1 Key State Atoms
// Calendar visibility state
export const calendarVisibleAtom = atom<boolean>(false);
// Selected schedule for action state
export const selectedScheduleAtom = atom<Schedule | null>(null);
// Schedule last updated timestamp
export const lastUpdatedAtom = atomWithStorage<string | null>(
"scheduleLastUpdated",
null
);14.2 State Flow
flowchart TD A[User Interaction] --> B[Component State] B --> C[Jotai Atom] C --> D{State Type?} D -- "URL State" --> E[URL Parameters] D -- "Local State" --> F[In-Memory Only] D -- "Persistent State" --> G[Secure Storage] E --> H[Page Rehydration] G --> H
15. Internationalization
The Schedule Listing module is fully internationalized using a type-safe i18n system:
Source: locales/
// Usage example
const { LL } = useLocalization();
return <Text>{LL.schedule.filter.status.completed()}</Text>;15.1 Supported Languages
- English (en)
- Spanish (es)
- Indonesian (id)
- Korean (ko)
- Portuguese (pt)
- Thai (th)
- Khmer (km)
16. Team Audit Integration
The Schedule Listing module integrates deeply with the Team Audit feature, allowing for collaborative audit management:
16.1 Team Report Start Flow
sequenceDiagram participant User participant Team Audit Card participant TeamReportStartBottomSheet participant TeamReportStartController participant StartTeamReportMutation participant TeamSessionAPI User->>Team Audit Card: Tap Start Team Audit Team Audit Card->>TeamReportStartController: openBottomSheet(scheduleId) TeamReportStartController->>TeamReportStartBottomSheet: Opens with schedule details TeamReportStartBottomSheet-->>User: Display team member assignment UI User->>TeamReportStartBottomSheet: Assign sections and confirm TeamReportStartBottomSheet->>StartTeamReportMutation: Start team session StartTeamReportMutation->>TeamSessionAPI: Create team session TeamSessionAPI-->>StartTeamReportMutation: Return session details StartTeamReportMutation-->>TeamReportStartController: Session created successfully TeamReportStartController-->>User: Navigate to team audit interface
Source: team-report-start-bottom-sheet.tsx
16.2 Team Audit Coordination
Team audits implement real-time coordination through:
- Role-based Access Control: Different capabilities based on user role
- Section Assignment: Distributing audit sections among team members
- Progress Tracking: Real-time updates on team member progress
- Conflict Resolution: Managing concurrent edits to the same section
- Consolidation: Team lead review and consolidation of team input
17. Error Handling
The Schedule Listing module implements comprehensive error handling:
17.1 Error Boundaries
Component-level error boundaries prevent cascading failures:
export default function ScheduleErrorBoundary({
children,
}: PropsWithChildren<unknown>) {
return (
<ErrorBoundary
FallbackComponent={ScheduleErrorFallback}
onError={(error) => {
captureException(error);
logError("ScheduleErrorBoundary", error);
}}
>
{children}
</ErrorBoundary>
);
}17.2 Query Error Handling
const { data, isLoading, error, refetch } = useScheduleQuery();
if (error) {
return (
<ErrorView message={LL.schedule.errors.loadingFailed()} onRetry={refetch} />
);
}17.3 Specific Error Types
- Network Errors: Handled with retry mechanisms and offline mode
- Authentication Errors: Redirect to login with return path
- Permission Errors: Show appropriate messaging based on user role
- Data Validation Errors: Prevent invalid data submission with clear feedback
- Unexpected Errors: Graceful degradation with error reporting
18. Technical Considerations
18.1 React Native Optimizations
- Render Optimization: Careful management of render cycles
- Memoization: Strategic use of useMemo and useCallback
- List Virtualization: Efficient rendering of large lists
- Image Optimization: Progressive loading and caching
- Animation Performance: Native-driven animations for smoothness
18.2 Data Synchronization
The Schedule Listing module implements a sophisticated data synchronization system:
flowchart TD A[App Start/Resume] --> B{Needs Sync?} B -- Yes --> C[Check Last Sync Time] B -- No --> D[Use Cached Data] C --> E{Stale Data?} E -- Yes --> F[Fetch Fresh Data] E -- No --> D G[Pull to Refresh] --> F H[Background Timer] --> C I[Connectivity Restored] --> J[Process Offline Queue] J --> K[Sync With Server]
19. Usage Examples
19.1 Viewing Daily Schedule
// Select the Daily tab
scheduleTabController.setActiveTab(ScheduleTabType.DAILY);
// Select a specific date
calendarController.selectDate(new Date(2025, 4, 15));
// View schedules grouped by status
viewByController.setViewBy("status");19.2 Finding Overdue Audits
// Go to Active Period view
scheduleTabController.setActiveTab(ScheduleTabType.ACTIVE_PERIOD);
// View by status
viewByController.setViewBy("status");
// Filter for overdue items
statusFilterController.setFilter("overdue");19.3 Starting a Team Audit
// Find and select team audit
const teamAudit = schedules.find((s) => s.type === "team");
startTeamReportController.openBottomSheet(teamAudit.id);
// Assign team members
startTeamReportController.assignSection({
userId: "user123",
sectionId: "section1",
});
// Initiate team session
startTeamReportController.startTeamReport();20. Conclusion
The Schedule Listing module provides a flexible, performant interface for users to interact with their scheduled audits. Its component-based architecture allows for easy maintenance and extension, while the comprehensive filtering system gives users powerful ways to organize and find relevant [schedules](../../Schedule/Schedule Listing/ScheduleListingOverview.md). The integration with [team audits](../Team Audit/TeamAuditOverview.md) and robust offline support ensure that users can continue their work in any environment.
The module is built with performance and scalability in mind, using best practices for React Native development, state management, and data fetching. The internationalization support ensures that the application is accessible to users around the world, while the error handling provides a smooth experience even in problematic scenarios.
By centralizing schedule management and providing rich visualization and filtering capabilities, the Schedule Listing module serves as a core part of the audit management experience.
Last Updated: 08 May 2025 at 11:13 am IST by samir