Skip to content

Conversation

FussuChalice
Copy link
Contributor

@FussuChalice FussuChalice commented Jun 29, 2025

Description

In this PR, I’ve added a new PDF template for exporting upcoming events and refactored the folder structure related to this feature for better clarity and maintainability.

Apologies for exceeding the 30-file change limit 🙏
Most of the changes are static assets (like icons), and the actual logic changes are minimal.

Also, I had to recreate some of the changes due to earlier errors, which caused extra file diffs in this PR. Sorry for the noise — everything should be working smoothly now.

Let me know if you'd like me to split or revise anything!

Fixes # (issue)

Type of change

  • New feature (non-breaking change which adds functionality)

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • Any dependent changes have been merged and published in downstream modules

Copy link

vercel bot commented Jun 29, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
staging-organized-app ✅ Ready (Inspect) Visit Preview Jul 28, 2025 4:20pm
test-organized-app ✅ Ready (Inspect) Visit Preview Jul 28, 2025 4:20pm

Copy link
Contributor

coderabbitai bot commented Jun 29, 2025

Walkthrough

This change introduces a comprehensive PDF export feature for upcoming events, adding new utility functions, React components, and type definitions to support PDF rendering. It refactors existing event logic to use new utilities, implements a custom export workflow, and standardizes icon and page component usage across the codebase. Several new icon components and a centralized export module for components are also included.

Changes

Cohort / File(s) Change Summary
PDF Export Feature for Upcoming Events
src/features/activities/upcoming_events/export_upcoming_events/index.tsx,
src/features/activities/upcoming_events/export_upcoming_events/useExportUpcomingEvents.tsx,
src/pages/activities/upcoming_events/index.tsx,
src/views/activities/upcoming_events/UpcomingEvent.tsx,
src/views/activities/upcoming_events/UpcomingEventDate.tsx,
src/views/activities/upcoming_events/UpcomingEventsList.tsx,
src/views/activities/upcoming_events/decoration_for_event.tsx,
src/views/activities/upcoming_events/index.tsx,
src/views/activities/upcoming_events/index.types.ts
Adds a full PDF export flow for upcoming events, including export button, export logic, event rendering components, icon decorations, and supporting type definitions.
Utility Function for Date Ranges
src/utils/date.ts,
src/features/activities/upcoming_events/upcoming_event/useUpcomingEvent.tsx
Adds getDatesBetweenDates utility and refactors event logic to use this function for date range generation.
Icon Components Standardization
src/views/components/icons/IconAirplaneTicket.tsx,
.../IconCalendarClock.tsx,
.../IconCampaign.tsx,
.../IconCart.tsx,
.../IconCorporateFare.tsx,
.../IconDate.tsx,
.../IconDiagnosis.tsx,
.../IconDistance.tsx,
.../IconJwHome.tsx,
.../IconLightbulb.tsx,
.../IconLocalLibrary.tsx,
.../IconStadium.tsx,
.../IconTranslate.tsx,
.../IconVacuum.tsx,
.../IconVoiceSelection.tsx,
.../IconWavingHand.tsx,
.../IconWine.tsx,
src/views/components/icons/index.ts,
src/views/components/icons/index.types.ts
Adds and standardizes multiple icon components, updates their exports, and adjusts prop types for consistency.
PDF Page and Document Components
src/views/components/document/index.tsx,
src/views/components/document/index.types.ts,
src/views/components/page/index.tsx,
src/views/components/page/index.types.ts,
src/views/components/page_header/index.tsx,
src/views/components/page_header/index.types.ts,
src/views/components/page_content/index.tsx,
src/views/components/page_content/index.types.ts,
src/views/components/page_bottom/index.tsx,
src/views/components/page_bottom/index.types.ts,
src/views/components/index.ts
Introduces reusable PDF document, page, header, content, and footer components with supporting type definitions and a central export module.
Field Service Groups Type Refactor and Style Update
src/views/congregation/field_service_groups/FSGGroup.tsx,
src/views/congregation/field_service_groups/FSGGroupMember.tsx,
src/views/congregation/field_service_groups/index.tsx,
src/views/congregation/field_service_groups/index.types.ts,
src/views/congregation/field_service_groups/index.styles.ts,
src/views/congregation/field_service_groups/PageHeader.tsx
Renames types from Type to Props, updates prop usage, removes a redundant header component, and replaces CSS variable lookups with hardcoded color values in styles.
Exports Update
src/views/index.ts
Adds export for TemplateUpcomingEvents component.
Other Minor Updates
src/views/meetings/midweek/S140/app_normal/S140WeekHeader.tsx
Updates icon usage by adding explicit props.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ExportUpcomingEventsButton
    participant useExportUpcomingEvents
    participant PDFGenerator (TemplateUpcomingEvents)
    participant FileSaver

    User->>ExportUpcomingEventsButton: Click "Export" button
    ExportUpcomingEventsButton->>useExportUpcomingEvents: handleExport()
    useExportUpcomingEvents->>useExportUpcomingEvents: Set isProcessing=true
    useExportUpcomingEvents->>useExportUpcomingEvents: Gather and format event data
    useExportUpcomingEvents->>PDFGenerator: Generate PDF blob with events
    PDFGenerator-->>useExportUpcomingEvents: Return PDF blob
    useExportUpcomingEvents->>FileSaver: Save PDF to device
    useExportUpcomingEvents->>useExportUpcomingEvents: Set isProcessing=false
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • sws2apps/organized-app#3335: Adds font registration for "Inter" in a PDF template for upcoming events, similar to this PR's PDF font handling.
  • sws2apps/organized-app#4412: Modifies date range formatting logic in the same file (useUpcomingEvent.tsx) that is refactored here for date handling.

Suggested labels

released

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3fc084d and f43dd91.

📒 Files selected for processing (1)
  • src/views/index.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/views/index.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Summary
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🧹 Nitpick comments (19)
src/views/congregation/field_service_groups/index.styles.ts (2)

78-78: Consider using a design system constant for border color.

The borderColor is hardcoded to #AAAAAA. Consider extracting this to a constant if it's used elsewhere for consistency.


91-91: Consider using a design system constant for border color.

The border color is hardcoded to #DADADA. Consider extracting this to a constant if it's used elsewhere for consistency.

src/views/components/document/index.tsx (1)

6-11: Consider making metadata configurable for better reusability.

The hardcoded metadata values work for the current use case but could limit reusability.

Consider making metadata configurable:

const Document = ({ 
  title, 
  children,
+ author = "sws2apps",
+ creator = "Organized", 
+ producer = "sws2apps (by react-pdf)"
}: PDFDocumentType) => {
  return (
    <ReactPDFDocument
-     author="sws2apps"
+     author={author}
      title={title}
-     creator="Organized"
+     creator={creator}
-     producer="sws2apps (by react-pdf)"
+     producer={producer}
    >
      {children}
    </ReactPDFDocument>
  );
};

This would require updating the PDFDocumentType interface accordingly.

src/views/congregation/upcoming_events/UpcomingEventsList.tsx (2)

7-28: Solid grouping logic with minor clarity improvements possible.

The event grouping and sorting logic is correct and handles edge cases well. The non-null assertion operators are technically safe given the surrounding logic, but could be made more explicit for better code clarity.

Consider storing the array references to avoid repeated map lookups:

  const sortEventsByYear = (events: UpcomingEventType[]) => {
    const yearMap = new Map<number, UpcomingEventType[]>();

    for (const event of events) {
      if (event._deleted) continue;

      const dateStr = event.event_data?.start;
      if (!dateStr) continue;

      const year = new Date(dateStr).getFullYear();

      if (!yearMap.has(year)) {
        yearMap.set(year, []);
      }

-     yearMap.get(year)!.push(event);
+     const yearEvents = yearMap.get(year)!;
+     yearEvents.push(event);
    }

    const sortedYears = Array.from(yearMap.keys()).sort((a, b) => a - b);

-   return sortedYears.map((year) => yearMap.get(year)!);
+   return sortedYears.map((year) => {
+     const events = yearMap.get(year)!;
+     return events;
+   });
  };

40-70: Verify events array safety in render logic.

The code assumes events[0] exists when accessing events[0].event_data.start for the key and year display. While this should be safe given the filtering logic, consider adding explicit checks for robustness.

      {sortedEvents.map((events) => (
+       {events.length > 0 && (
        <View
-         key={new Date(events[0].event_data.start).getFullYear()}
+         key={new Date(events[0].event_data.start).getFullYear()}
          style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}
        >
          <View
            style={{
              border: '1px solid #D5DFFD',
              padding: '5px 8px',
              borderRadius: '4px',
              backgroundColor: '#F2F5FF',
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'center',
            }}
          >
            <Text
              style={{
                fontWeight: 600,
                fontSize: '12px',
                color: '#5065D0',
              }}
            >
              {new Date(events[0].event_data.start).getFullYear()}
            </Text>
          </View>
          {events.map((eventData) => (
            <UpcomingEvent key={eventData.event_data.start} event={eventData} />
          ))}
        </View>
+       )}
      ))}
src/features/congregation/upcoming_events/export_upcoming_events/useExportUpcomingEvents.tsx (1)

38-38: Consider filename sanitization for cross-platform compatibility.

The filename generation uses replaceAll(' ', '_') but might need additional sanitization for special characters that could be problematic on different operating systems.

-     const filename = `${t('tr_upcomingEvents').replaceAll(' ', '_')}.pdf`;
+     const filename = `${t('tr_upcomingEvents').replace(/[^a-zA-Z0-9]/g, '_')}.pdf`;
src/views/components/page_bottom/index.tsx (1)

16-64: Consider consistent styling approach.

The component mixes hardcoded color values with CSS variable calls. For PDF components, consider using a consistent approach with either all hardcoded values or a centralized theme configuration.

src/views/congregation/upcoming_events/index.tsx (1)

11-15: Address unused prop in component signature.

The shortDateFormat prop is defined in TemplateUpcomingEventsProps but is not used anywhere in this component. Consider removing it from the type definition if it's truly unused, or implement its intended functionality.

Either remove the unused prop from the type definition:

export type TemplateUpcomingEventsProps = {
  events: UpcomingEventType[];
-  shortDateFormat: string;
  lang: string;
  congregation: string;
};

Or destructure and use it if there's intended functionality:

const TemplateUpcomingEvents = ({
  events,
  congregation,
  lang,
+  shortDateFormat,
}: TemplateUpcomingEventsProps) => {
src/views/congregation/upcoming_events/UpcomingEventDate.tsx (2)

99-99: Improve description condition check.

The current condition description !== '' doesn't handle undefined/null values properly. Since description is optional, this could cause unexpected behavior.

-        {description !== '' && (
+        {description && description !== '' && (

Or more concisely:

-        {description !== '' && (
+        {description && (

46-46: Consider using CSS variables for color consistency.

The component uses hardcoded hex colors instead of CSS variables. For better maintainability and theming consistency, consider using getCSSPropertyValue() for colors like other components in the codebase.

For example:

-              backgroundColor: '#F2F5FF',
+              backgroundColor: getCSSPropertyValue('--some-background-color'),

Also applies to: 55-55, 64-64, 75-75, 94-94, 104-104

src/views/components/page_header/index.tsx (1)

39-39: Consider centralizing color values for consistency.

The component uses hardcoded colors (#FEFEFE, #000000) mixed with CSS variables. For better maintainability, consider using a consistent approach throughout the component.

Also applies to: 49-49, 78-78, 95-95

src/views/components/icons/IconAirplaneTicket.tsx (2)

4-4: Annotate the component with an explicit React.FC type

Typing the component as React.FC<IconProps> (or FC) tightens the contract, enables better IntelliSense, and prevents implicit-any return types:

-const IconAirplaneTicket = ({ size = 24, color = '#222222' }: IconProps) => {
+const IconAirplaneTicket: React.FC<IconProps> = ({ size = 24, color = '#222222' }) => {

If your project still uses the classic JSX runtime, remember to import React from 'react';; otherwise ensure tsconfig.json is set to "jsx": "react-jsx".


6-14: Consider memoising repeated icon components

Icons are pure functions of their props; wrapping them with React.memo avoids needless re-rendering when used repeatedly in complex PDF pages:

-const IconAirplaneTicket: React.FC<IconProps> = ({ size = 24, color = '#222222' }) => {
+const IconAirplaneTicket: React.FC<IconProps> = React.memo(({ size = 24, color = '#222222' }) => {-};
+});

(This refactor applies to the whole icon set for a low-cost perf win.)

src/views/components/icons/IconLightbulb.tsx (2)

4-4: Apply the same explicit typing pattern

-const IconLightbulb = ({ size = 24, color = '#222222' }: IconProps) => {
+const IconLightbulb: React.FC<IconProps> = ({ size = 24, color = '#222222' }) => {

This stays consistent with the rest of the codebase and with the recommendation given for IconAirplaneTicket.


6-14: Optional: wrap with React.memo

As above, memoising the component can shave off redundant renders when the same icon is scattered across pages.

src/views/components/icons/IconVacuum.tsx (2)

4-4: Add React.FC typing for stronger type-safety

-const IconVacuum = ({ size = 24, color = '#222222' }: IconProps) => {
+const IconVacuum: React.FC<IconProps> = ({ size = 24, color = '#222222' }) => {

6-14: Memoisation – same comment as other icons

React.memo is a zero-risk optimisation here.

src/views/components/icons/IconVoiceSelection.tsx (2)

4-4: Consistent component typing

-const IconVoiceSelection = ({ size = 24, color = '#222222' }: IconProps) => {
+const IconVoiceSelection: React.FC<IconProps> = ({ size = 24, color = '#222222' }) => {

6-14: Optional React.memo optimisation

Same rationale as for the other icons.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 448395b and b19cf63.

⛔ Files ignored due to path filters (2)
  • src/locales/en/forms-templates.json is excluded by !**/*.json
  • src/locales/en/general.json is excluded by !**/*.json
📒 Files selected for processing (49)
  • src/features/congregation/upcoming_events/export_upcoming_events/index.tsx (1 hunks)
  • src/features/congregation/upcoming_events/export_upcoming_events/useExportUpcomingEvents.tsx (1 hunks)
  • src/features/congregation/upcoming_events/upcoming_event/useUpcomingEvent.tsx (1 hunks)
  • src/pages/congregation/upcoming_events/index.tsx (2 hunks)
  • src/utils/date.ts (1 hunks)
  • src/views/components/document/index.tsx (1 hunks)
  • src/views/components/document/index.types.ts (1 hunks)
  • src/views/components/icons/IconAirplaneTicket.tsx (1 hunks)
  • src/views/components/icons/IconCalendarClock.tsx (1 hunks)
  • src/views/components/icons/IconCampaign.tsx (1 hunks)
  • src/views/components/icons/IconCart.tsx (1 hunks)
  • src/views/components/icons/IconCorporateFare.tsx (1 hunks)
  • src/views/components/icons/IconDate.tsx (1 hunks)
  • src/views/components/icons/IconDiagnosis.tsx (1 hunks)
  • src/views/components/icons/IconDistance.tsx (1 hunks)
  • src/views/components/icons/IconJwHome.tsx (1 hunks)
  • src/views/components/icons/IconLightbulb.tsx (1 hunks)
  • src/views/components/icons/IconLocalLibrary.tsx (1 hunks)
  • src/views/components/icons/IconStadium.tsx (1 hunks)
  • src/views/components/icons/IconTranslate.tsx (1 hunks)
  • src/views/components/icons/IconVacuum.tsx (1 hunks)
  • src/views/components/icons/IconVoiceSelection.tsx (1 hunks)
  • src/views/components/icons/IconWavingHand.tsx (1 hunks)
  • src/views/components/icons/IconWine.tsx (1 hunks)
  • src/views/components/icons/index.ts (1 hunks)
  • src/views/components/icons/index.types.ts (0 hunks)
  • src/views/components/index.ts (1 hunks)
  • src/views/components/page/index.tsx (1 hunks)
  • src/views/components/page/index.types.ts (1 hunks)
  • src/views/components/page_bottom/index.tsx (1 hunks)
  • src/views/components/page_bottom/index.types.ts (1 hunks)
  • src/views/components/page_content/index.tsx (1 hunks)
  • src/views/components/page_content/index.types.ts (1 hunks)
  • src/views/components/page_header/index.tsx (1 hunks)
  • src/views/components/page_header/index.types.ts (1 hunks)
  • src/views/congregation/field_service_groups/FSGGroup.tsx (1 hunks)
  • src/views/congregation/field_service_groups/FSGGroupMember.tsx (1 hunks)
  • src/views/congregation/field_service_groups/PageHeader.tsx (0 hunks)
  • src/views/congregation/field_service_groups/index.styles.ts (3 hunks)
  • src/views/congregation/field_service_groups/index.tsx (1 hunks)
  • src/views/congregation/field_service_groups/index.types.ts (1 hunks)
  • src/views/congregation/upcoming_events/UpcomingEvent.tsx (1 hunks)
  • src/views/congregation/upcoming_events/UpcomingEventDate.tsx (1 hunks)
  • src/views/congregation/upcoming_events/UpcomingEventsList.tsx (1 hunks)
  • src/views/congregation/upcoming_events/decoration_for_event.tsx (1 hunks)
  • src/views/congregation/upcoming_events/index.tsx (1 hunks)
  • src/views/congregation/upcoming_events/index.types.ts (1 hunks)
  • src/views/index.ts (1 hunks)
  • src/views/meetings/midweek/S140/app_normal/S140WeekHeader.tsx (1 hunks)
💤 Files with no reviewable changes (2)
  • src/views/components/icons/index.types.ts
  • src/views/congregation/field_service_groups/PageHeader.tsx
🧰 Additional context used
🧬 Code Graph Analysis (32)
src/views/components/icons/IconJwHome.tsx (1)
src/views/components/icons/index.types.ts (1)
  • IconProps (1-4)
src/views/congregation/field_service_groups/FSGGroupMember.tsx (1)
src/views/congregation/field_service_groups/index.types.ts (1)
  • FSGGroupMemberProps (13-15)
src/views/components/page/index.tsx (1)
src/views/components/page/index.types.ts (1)
  • PageType (3-6)
src/views/components/icons/IconCampaign.tsx (1)
src/views/components/icons/index.types.ts (1)
  • IconProps (1-4)
src/views/components/icons/IconDistance.tsx (1)
src/views/components/icons/index.types.ts (1)
  • IconProps (1-4)
src/views/components/icons/IconWine.tsx (1)
src/views/components/icons/index.types.ts (1)
  • IconProps (1-4)
src/views/components/icons/IconCalendarClock.tsx (1)
src/views/components/icons/index.types.ts (1)
  • IconProps (1-4)
src/views/components/icons/IconLightbulb.tsx (1)
src/views/components/icons/index.types.ts (1)
  • IconProps (1-4)
src/features/congregation/upcoming_events/export_upcoming_events/useExportUpcomingEvents.tsx (3)
src/states/settings.ts (3)
  • JWLangLocaleState (208-216)
  • congNameState (27-31)
  • shortDateFormatState (92-101)
src/states/upcoming_events.ts (1)
  • upcomingEventsState (8-8)
src/services/i18n/translation.ts (1)
  • getMessageByCode (43-45)
src/views/congregation/upcoming_events/UpcomingEventsList.tsx (2)
src/views/congregation/upcoming_events/index.types.ts (1)
  • UpcomingEventsListProps (10-12)
src/definition/upcoming_events.ts (1)
  • UpcomingEventType (25-38)
src/views/congregation/field_service_groups/FSGGroup.tsx (1)
src/views/congregation/field_service_groups/index.types.ts (1)
  • FSGGroupProps (9-11)
src/views/components/document/index.tsx (1)
src/views/components/document/index.types.ts (1)
  • PDFDocumentType (4-7)
src/views/components/icons/IconVoiceSelection.tsx (1)
src/views/components/icons/index.types.ts (1)
  • IconProps (1-4)
src/views/components/icons/IconDiagnosis.tsx (1)
src/views/components/icons/index.types.ts (1)
  • IconProps (1-4)
src/views/components/icons/IconVacuum.tsx (1)
src/views/components/icons/index.types.ts (1)
  • IconProps (1-4)
src/views/components/icons/IconAirplaneTicket.tsx (1)
src/views/components/icons/index.types.ts (1)
  • IconProps (1-4)
src/views/components/icons/IconTranslate.tsx (1)
src/views/components/icons/index.types.ts (1)
  • IconProps (1-4)
src/views/components/icons/IconDate.tsx (1)
src/views/components/icons/index.types.ts (1)
  • IconProps (1-4)
src/views/components/icons/IconLocalLibrary.tsx (1)
src/views/components/icons/index.types.ts (1)
  • IconProps (1-4)
src/views/components/icons/IconStadium.tsx (1)
src/views/components/icons/index.types.ts (1)
  • IconProps (1-4)
src/views/congregation/upcoming_events/UpcomingEventDate.tsx (4)
src/views/congregation/upcoming_events/index.types.ts (1)
  • UpcomingEventDateProps (18-23)
src/services/i18n/translation.ts (1)
  • generateWeekday (21-33)
src/utils/date.ts (1)
  • formatDate (15-17)
src/utils/common.ts (1)
  • getCSSPropertyValue (261-265)
src/views/components/icons/IconCorporateFare.tsx (1)
src/views/components/icons/index.types.ts (1)
  • IconProps (1-4)
src/views/congregation/upcoming_events/index.tsx (2)
src/views/congregation/upcoming_events/index.types.ts (1)
  • TemplateUpcomingEventsProps (3-8)
src/constants/index.ts (1)
  • LANGUAGE_LIST (31-361)
src/views/components/page_bottom/index.tsx (3)
src/views/components/page_bottom/index.types.ts (1)
  • PageBottomProps (3-8)
src/utils/common.ts (1)
  • getCSSPropertyValue (261-265)
src/utils/date.ts (1)
  • formatDate (15-17)
src/views/components/icons/IconCart.tsx (1)
src/views/components/icons/index.types.ts (1)
  • IconProps (1-4)
src/views/congregation/field_service_groups/index.types.ts (1)
src/definition/field_service_groups.ts (1)
  • FieldServiceGroupExportType (22-28)
src/views/components/page_header/index.tsx (2)
src/views/components/page_header/index.types.ts (1)
  • PageHeaderProps (3-10)
src/utils/common.ts (1)
  • getCSSPropertyValue (261-265)
src/views/congregation/upcoming_events/UpcomingEvent.tsx (4)
src/views/congregation/upcoming_events/index.types.ts (1)
  • UpcomingEventProps (14-16)
src/states/settings.ts (1)
  • hour24FormatState (103-112)
src/utils/date.ts (2)
  • formatDate (15-17)
  • getDatesBetweenDates (472-484)
src/views/congregation/upcoming_events/decoration_for_event.tsx (1)
  • decorationsForEvent (20-85)
src/views/congregation/upcoming_events/index.types.ts (1)
src/definition/upcoming_events.ts (1)
  • UpcomingEventType (25-38)
src/views/congregation/field_service_groups/index.tsx (2)
src/views/congregation/field_service_groups/index.types.ts (1)
  • TemplateFieldServiceGroupsProps (3-7)
src/constants/index.ts (1)
  • LANGUAGE_LIST (31-361)
src/views/components/icons/IconWavingHand.tsx (1)
src/views/components/icons/index.types.ts (1)
  • IconProps (1-4)
src/views/components/page_content/index.tsx (1)
src/views/components/page_content/index.types.ts (1)
  • PageContentProps (3-6)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Code QL
  • GitHub Check: Summary
🔇 Additional comments (49)
src/views/components/document/index.types.ts (1)

1-7: LGTM! Clean type definition with helpful naming context.

The type definition is well-structured and the comment explaining the naming choice to avoid conflict with React's default DocumentType is valuable for maintainability.

src/views/components/page_content/index.types.ts (1)

1-6: LGTM! Simple and well-structured prop types.

The type definition is clean with appropriate optional/required properties that align with typical React component patterns.

src/views/components/page_header/index.types.ts (1)

1-10: LGTM! Comprehensive and well-typed page header props.

The type definition effectively uses union types for variants and provides good flexibility with optional properties. The JSX.Element type for the icon is appropriate.

src/views/components/icons/IconDistance.tsx (1)

1-17: LGTM! Well-structured icon component following established patterns.

The component correctly implements the IconProps interface, uses appropriate default values, and follows the pattern established by other icon components in the codebase for @react-pdf/renderer usage.

src/views/index.ts (1)

7-7: LGTM! Clean export addition following established patterns.

The new TemplateUpcomingEvents export follows the consistent naming convention and is properly grouped with other congregation templates.

src/features/congregation/upcoming_events/upcoming_event/useUpcomingEvent.tsx (1)

8-8: Good refactoring! Centralizing utility functions improves maintainability.

Moving getDatesBetweenDates to a shared utility module promotes code reuse and reduces duplication across the codebase.

src/views/congregation/field_service_groups/FSGGroup.tsx (2)

3-3: Improved naming convention with "Props" suffix.

The change from FSGGroupType to FSGGroupProps better reflects that this type defines component props, following React TypeScript conventions.


7-7: Type annotation updated consistently.

The component prop type annotation correctly uses the renamed FSGGroupProps type.

src/views/meetings/midweek/S140/app_normal/S140WeekHeader.tsx (1)

17-17: Good addition of explicit icon props for better control.

Adding size={10} and backgroundColor="none" provides explicit control over the icon's appearance and supports the broader icon standardization effort across the codebase.

src/views/components/page/index.types.ts (1)

1-6: Well-structured type definition for PDF page components.

The PageType definition cleanly encapsulates the required props for PDF page components with appropriate typing for font styling and ReactNode children.

src/views/congregation/field_service_groups/FSGGroupMember.tsx (1)

2-2: LGTM: Type renaming follows consistent naming convention.

The change from FSGGroupMemberType to FSGGroupMemberProps aligns with the broader refactor to use "Props" suffix for component prop types, improving consistency across the codebase.

Also applies to: 5-5

src/pages/congregation/upcoming_events/index.tsx (1)

9-9: LGTM: Clean integration of export functionality.

The ExportUpcomingEvents component is properly imported and integrated into the admin-only button group, following the existing conditional rendering pattern and logical button ordering.

Also applies to: 36-36

src/views/components/page_bottom/index.types.ts (1)

1-8: LGTM: Well-structured type definition.

The PageBottomProps type is comprehensive with appropriate types for each property. The optional fixed prop and ReactNode type for qrCode are correctly defined for PDF footer functionality.

src/views/components/page_content/index.tsx (1)

4-18: LGTM: Well-implemented reusable layout component.

The PageContent component follows good practices with proper default value handling (gap ?? 16), correct flex styling for PDF rendering, and clean prop destructuring. The component provides good reusability for PDF layouts.

src/views/components/icons/IconWine.tsx (1)

4-15: LGTM: Well-implemented SVG icon component.

The IconWine component follows the established pattern for PDF renderer icons with proper prop defaults, correct SVG structure, and appropriate use of the color prop for fill styling. The implementation is consistent with other icon components in the codebase.

src/views/congregation/field_service_groups/index.styles.ts (2)

2-2: Import remains necessary
The getCSSPropertyValue function is still used for the borderRadius property in this file:

  • src/views/congregation/field_service_groups/index.styles.ts – borderRadius: getCSSPropertyValue('--radius-xs')

40-40: Verify CSS variable for repeated hardcoded color
I spotted many occurrences of #3B4CA3 across the codebase—ensure this hex value is an approved design-system token and replace all instances with the corresponding CSS variable or theme constant if one exists.

Key locations:

  • src/views/congregation/field_service_groups/index.styles.ts
  • src/views/congregation/upcoming_events/UpcomingEventDate.tsx
  • src/views/meetings/weekend/index.styles.ts
  • src/views/meetings/midweek/S140/app_normal/index.tsx
  • src/components/illustrations/IllustrationSecretary.tsx
  • src/components/icons/IconMale.tsx

If #3B4CA3 is the “brand” or “primary” blue, define it once (e.g. --color-primary-blue) and import/use that variable everywhere instead of hardcoding.

src/views/components/index.ts (1)

1-6: Well-structured barrel export pattern.

This centralized export approach improves import organization and provides a clean API for consuming these PDF components.

src/views/components/icons/IconJwHome.tsx (1)

4-23: Well-implemented icon component following established patterns.

The component correctly implements the IconProps interface and follows the established pattern for PDF-compatible SVG icons. The use of Group to contain multiple paths is appropriate.

src/views/components/icons/IconCampaign.tsx (1)

4-15: Consistent icon implementation following established patterns.

The component correctly implements the IconProps interface and maintains consistency with other icon components in the codebase.

src/views/components/icons/IconTranslate.tsx (1)

4-15: Consistent icon implementation following established patterns.

The component correctly implements the IconProps interface and maintains consistency with other icon components in the codebase. The complex path appropriately represents the translation/language concept.

src/views/components/icons/IconAirplaneTicket.tsx (1)

1-18: Well-implemented icon component following established patterns.

The component correctly implements the PDF icon pattern with proper TypeScript typing, appropriate defaults, and clean SVG structure. The implementation is consistent with the broader icon system being introduced.

src/views/components/icons/IconLightbulb.tsx (1)

1-18: Consistent implementation with established icon patterns.

The component maintains excellent consistency with other icon components in the system, using identical prop handling, defaults, and SVG structure. The implementation is clean and follows TypeScript best practices.

src/views/components/icons/IconVacuum.tsx (1)

1-18: Excellent consistency with the icon component system.

The implementation perfectly follows the established icon pattern with proper TypeScript typing, consistent defaults, and clean SVG structure. The component integrates well with the broader icon library.

src/views/components/page/index.tsx (1)

1-25: Well-designed page wrapper promoting consistency.

This component provides an excellent abstraction over @react-pdf/renderer's Page component, standardizing A4 page layout with consistent styling while allowing dynamic font application. The implementation promotes code reuse and maintains consistency across PDF documents.

src/views/components/icons/IconVoiceSelection.tsx (1)

1-18: Perfect consistency completing the icon component system.

The component maintains the same high-quality implementation pattern as all other icon components in this PR. The consistent approach across all icons demonstrates excellent architectural planning and will ensure easy maintenance and extensibility of the icon system.

src/views/components/icons/IconDiagnosis.tsx (1)

1-17: LGTM! Clean icon component implementation.

The component follows proper TypeScript patterns, correctly uses @react-pdf/renderer primitives, and implements the IconProps interface consistently.

src/views/components/icons/IconCalendarClock.tsx (1)

1-17: LGTM! Consistent icon component implementation.

The component follows the established patterns and correctly implements the IconProps interface. The viewBox dimensions (24 x 25) appear intentional for the calendar-clock design.

src/views/components/icons/IconCorporateFare.tsx (1)

1-17: LGTM! Follows established icon component patterns.

The component is consistent with other icon components in the codebase and properly implements the IconProps interface.

src/views/congregation/upcoming_events/decoration_for_event.tsx (1)

1-85: Clean icon mapping implementation with consistent structure.

The centralized mapping of event types to icons is well-organized and provides a maintainable way to manage event decorations. The consistent structure makes it easy to add or modify event-icon associations.

src/views/components/icons/IconStadium.tsx (1)

1-18: Well-implemented SVG icon component following established patterns.

The component correctly implements the IconProps interface, uses appropriate defaults, and follows the consistent structure established for other icon components. The SVG implementation is properly configured with viewBox and path data.

src/features/congregation/upcoming_events/export_upcoming_events/index.tsx (1)

1-28: LGTM! Clean and well-structured export component.

The component follows React best practices with proper separation of concerns using custom hooks, conditional rendering for loading states, and internationalization support. The code is readable and maintainable.

src/views/components/icons/IconCart.tsx (1)

1-73: LGTM! Well-implemented PDF icon component.

The component correctly follows the established pattern for PDF icons using @react-pdf/renderer primitives, properly handles the IconProps interface, and maintains consistency with other icon components in the codebase.

src/views/congregation/field_service_groups/index.types.ts (1)

3-15: LGTM! Improved type naming for better semantic accuracy.

The refactoring from "Type" to "Props" suffix better reflects that these types define component props rather than general data structures, following React/TypeScript naming conventions.

src/views/components/icons/IconWavingHand.tsx (1)

1-17: LGTM! Good refactoring for consistency and flexibility.

The refactoring successfully standardizes the icon component to match the established pattern with configurable size and color props, improving consistency across the icon library.

src/views/congregation/upcoming_events/index.tsx (2)

18-21: LGTM: Font selection logic is well-implemented.

The font selection logic correctly falls back to 'Inter' when no specific font is found for the language, ensuring proper text rendering across different locales.


6-6: No icon inconsistency detected

The IconDate import in src/views/congregation/upcoming_events/index.tsx is correctly used for the header, and IconCalendarClock is intentionally reserved for individual event decorations in decoration_for_event.tsx. No change needed here.

Likely an incorrect or invalid review comment.

src/views/congregation/upcoming_events/UpcomingEventDate.tsx (1)

21-26: LGTM: Weekday calculation correctly handles Sunday edge case.

The logic properly adjusts Sunday (getDay() returns 0) to index 6 and shifts other days down by 1 to match the Monday-first weekday array from generateWeekday().

src/views/congregation/upcoming_events/UpcomingEvent.tsx (3)

63-66: LGTM: Icon cloning with dynamic props is well-implemented.

The use of cloneElement to pass size and backgroundColor props to the icon components is a clean approach for consistent styling across different event types.


89-111: LGTM: Complex conditional rendering logic is well-structured.

The nested conditional logic properly handles different combinations of event duration and category, providing appropriate date display for single-day events, multi-day events, and special campaign weeks.


19-30: Fix variable dependency order issue.

The eventDaysCountIndicator function (lines 19-24) references eventDates which is declared later (lines 27-30). This will cause a ReferenceError at runtime.

Move the eventDates declaration before eventDaysCountIndicator:

const UpcomingEvent = ({ event }: UpcomingEventProps) => {
  const { t } = useAppTranslation();
  const hour24 = useAtomValue(hour24FormatState);

+  const eventDates = getDatesBetweenDates(
+    new Date(event.event_data.start),
+    new Date(event.event_data.end)
+  );
+
  const eventDaysCountIndicator = () => {
    const shortMonth = formatDate(eventDates[0], 'LLL');
    const startDay = formatDate(eventDates[0], 'd');
    const endDay = formatDate(eventDates[eventDates.length - 1], 'd');
    return `${shortMonth}. ${startDay}-${endDay}`;
  };

  const eventTime = `${formatDate(new Date(event.event_data.start), hour24 ? 'HH:mm' : 'hh:mm a')} - ${formatDate(new Date(event.event_data.end), hour24 ? 'HH:mm' : 'hh:mm a')}`;
-  const eventDates = getDatesBetweenDates(
-    new Date(event.event_data.start),
-    new Date(event.event_data.end)
-  );

Likely an incorrect or invalid review comment.

src/views/congregation/upcoming_events/index.types.ts (2)

3-8: LGTM: Type definitions are well-structured.

The type definitions properly model the component props and provide good type safety. The shortDateFormat unused prop issue is already addressed in the main component review.


18-23: LGTM: UpcomingEventDateProps type is comprehensive.

The type definition properly handles all the optional properties and provides flexibility for different date display scenarios.

src/views/components/page_header/index.tsx (1)

13-103: LGTM: Switch-based variant handling is clean and maintainable.

The component properly separates the two layout variants with clear, distinct styling. The structure allows for easy extension with additional variants if needed.

src/views/congregation/field_service_groups/index.tsx (4)

8-9: LGTM! Clean import organization for new components.

The imports for the new icon and custom PDF components are well-organized and follow the established patterns in the codebase.


27-34: LGTM! Enhanced PageHeader with proper prop structure.

The new PageHeader component usage is well-structured with clear props for congregationName, variant, icon, title, and fixed. The addition of the IconGroups icon enhances the visual presentation.


27-40: PageContent gap prop handling verified

The PageContent component correctly reads the gap prop (falling back to 16) and applies it via the gap style on its container. gap={10} will render exactly as expected. No further changes needed.


25-26: Custom PDF wrappers correctly forward props and maintain functionality

I verified that:

  • src/views/components/document/index.tsx wraps ReactPDFDocument, forwarding the title prop (and applying fixed metadata) and rendering children.
  • src/views/components/page/index.tsx wraps ReactPDFPage, applies the passed font via style={{ fontFamily: font }}, and renders children.

No further changes needed.

src/views/components/icons/index.ts (1)

2-18: LGTM! Consistent icon export expansion.

The 17 new icon exports follow the established naming convention (IconCamelCase) and export pattern. The alphabetical organization makes the module easy to navigate and maintain.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jul 11, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/views/congregation/upcoming_events/UpcomingEventsList.tsx (1)

19-39: Consider extracting inline styles for better maintainability.

The year header styling is comprehensive and visually appropriate. Consider extracting the inline styles to a separate styles object for better maintainability.

+const styles = {
+  yearHeader: {
+    border: '1px solid #D5DFFD',
+    padding: '5px 8px',
+    borderRadius: '4px',
+    backgroundColor: '#F2F5FF',
+    display: 'flex',
+    alignItems: 'center',
+    justifyContent: 'center',
+  },
+  yearText: {
+    fontWeight: 600,
+    fontSize: '12px',
+    color: '#5065D0',
+  },
+};
+
 const UpcomingEventsList = ({ events }: UpcomingEventsListProps) => {
   return (
     <View
       style={{
         display: 'flex',
         flexDirection: 'column',
         gap: '16px',
       }}
     >
-      {events.map((events) => (
+      {events.map((yearEvents) => (
         <View
-          key={events[0].year}
+          key={yearEvents[0].year}
           style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}
         >
           <View
-            style={{
-              border: '1px solid #D5DFFD',
-              padding: '5px 8px',
-              borderRadius: '4px',
-              backgroundColor: '#F2F5FF',
-              display: 'flex',
-              alignItems: 'center',
-              justifyContent: 'center',
-            }}
+            style={styles.yearHeader}
           >
             <Text
-              style={{
-                fontWeight: 600,
-                fontSize: '12px',
-                color: '#5065D0',
-              }}
+              style={styles.yearText}
             >
-              {events[0].year}
+              {yearEvents[0].year}
             </Text>
           </View>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 71bc1db and a9865c1.

📒 Files selected for processing (6)
  • src/features/congregation/upcoming_events/export_upcoming_events/useExportUpcomingEvents.tsx (1 hunks)
  • src/utils/date.ts (1 hunks)
  • src/views/congregation/upcoming_events/UpcomingEvent.tsx (1 hunks)
  • src/views/congregation/upcoming_events/UpcomingEventDate.tsx (1 hunks)
  • src/views/congregation/upcoming_events/UpcomingEventsList.tsx (1 hunks)
  • src/views/congregation/upcoming_events/index.types.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/views/congregation/upcoming_events/UpcomingEventDate.tsx
  • src/features/congregation/upcoming_events/export_upcoming_events/useExportUpcomingEvents.tsx
  • src/views/congregation/upcoming_events/UpcomingEvent.tsx
  • src/utils/date.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Socket Security: Pull Request Alerts
  • GitHub Check: Summary
🔇 Additional comments (6)
src/views/congregation/upcoming_events/UpcomingEventsList.tsx (1)

5-13: LGTM!

The component structure is clean with proper TypeScript typing and appropriate flex layout for PDF rendering.

src/views/congregation/upcoming_events/index.types.ts (5)

6-16: LGTM!

The TemplateUpcomingEventType is comprehensive and well-structured with appropriate property types and clear naming conventions.


18-23: LGTM!

The props structure appropriately supports PDF template rendering with event grouping and localization requirements.


25-27: LGTM!

Clean and focused props interface for the events list component.


29-31: LGTM!

Appropriately simple and clean interface for the individual event component.


33-38: LGTM!

Well-designed interface with appropriate required and optional properties for flexible date rendering.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jul 28, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (4)
src/views/activities/upcoming_events/UpcomingEventDate.tsx (1)

22-106: Consider extracting hardcoded colors to constants.

The component is well-structured and functionally correct, but contains several hardcoded color values that could benefit from centralization for maintainability and consistency.

Consider creating a color constants object or using CSS variables:

const PDF_COLORS = {
  dateBackground: '#F2F5FF',
  datePrimary: '#3B4CA3',
  textPrimary: '#222222',
  textSecondary: '#505050',
} as const;

Then use these constants throughout the component styling instead of hardcoded values.

src/features/activities/upcoming_events/export_upcoming_events/useExportUpcomingEvents.tsx (2)

91-91: Remove debug console.log statement.

This console.log should be removed before production deployment.

-      console.log(eventsForPDF);

68-73: Potential issue with date range logic for single-day events.

The eventDaysCountIndicator function assumes the event spans multiple days, but it could be called for single-day events where startDay and endDay are the same.

Consider handling single-day events differently:

             const eventDaysCountIndicator = () => {
               const shortMonth = formatDate(eventDates[0], 'LLL');
               const startDay = formatDate(eventDates[0], 'd');
               const endDay = formatDate(eventDates[eventDates.length - 1], 'd');
-              return `${shortMonth}. ${startDay}-${endDay}`;
+              return eventDates.length === 1 
+                ? `${shortMonth}. ${startDay}`
+                : `${shortMonth}. ${startDay}-${endDay}`;
             };
src/views/activities/upcoming_events/UpcomingEvent.tsx (1)

72-90: Consider simplifying complex conditional rendering logic.

The nested ternary operators make the code harder to read and maintain. Consider extracting the date rendering logic into a separate function.

Consider refactoring to improve readability:

+        {(() => {
+          if (event.duration === UpcomingEventDuration.SingleDay) {
+            return <UpcomingEventDate date={new Date(event.start)} title={event.time} />;
+          }
+          
+          if (event.category === UpcomingEventCategory.SpecialCampaignWeek) {
+            return (
+              <UpcomingEventDate
+                date={event.dates[0]}
+                title={t('tr_everyDay')}
+                description={t('tr_days', { daysCount: event.dates.length })}
+                dayIndicatorText={event.eventDaysCountIndicator}
+              />
+            );
+          }
+          
+          return event.dates.map((eventDate, eventDateIndex) => (
+            <UpcomingEventDate
+              key={new Date(eventDate).toISOString()}
+              date={eventDate}
+              title={t('tr_wholeDay')}
+              description={`${t('tr_day')} ${eventDateIndex + 1}/${event.dates.length}`}
+            />
+          ));
+        })()}
-        {event.duration === UpcomingEventDuration.SingleDay ? (
-          <UpcomingEventDate date={new Date(event.start)} title={event.time} />
-        ) : event.category !== UpcomingEventCategory.SpecialCampaignWeek ? (
-          event.dates.map((eventDate, eventDateIndex) => (
-            <UpcomingEventDate
-              key={new Date(eventDate).toISOString()}
-              date={eventDate}
-              title={t('tr_wholeDay')}
-              description={`${t('tr_day')} ${eventDateIndex + 1}/${event.dates.length}`}
-            />
-          ))
-        ) : (
-          <UpcomingEventDate
-            date={event.dates[0]}
-            title={t('tr_everyDay')}
-            description={t('tr_days', { daysCount: event.dates.length })}
-            dayIndicatorText={event.eventDaysCountIndicator}
-          />
-        )}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a9865c1 and 3fc084d.

⛔ Files ignored due to path filters (1)
  • src/locales/en/general.json is excluded by !**/*.json
📒 Files selected for processing (11)
  • src/features/activities/upcoming_events/export_upcoming_events/index.tsx (1 hunks)
  • src/features/activities/upcoming_events/export_upcoming_events/useExportUpcomingEvents.tsx (1 hunks)
  • src/features/activities/upcoming_events/upcoming_event/useUpcomingEvent.tsx (2 hunks)
  • src/pages/activities/upcoming_events/index.tsx (2 hunks)
  • src/utils/date.ts (1 hunks)
  • src/views/activities/upcoming_events/UpcomingEvent.tsx (1 hunks)
  • src/views/activities/upcoming_events/UpcomingEventDate.tsx (1 hunks)
  • src/views/activities/upcoming_events/UpcomingEventsList.tsx (1 hunks)
  • src/views/activities/upcoming_events/decoration_for_event.tsx (1 hunks)
  • src/views/activities/upcoming_events/index.tsx (1 hunks)
  • src/views/activities/upcoming_events/index.types.ts (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • src/views/activities/upcoming_events/decoration_for_event.tsx
  • src/views/activities/upcoming_events/index.types.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/utils/date.ts
🧰 Additional context used
🧠 Learnings (1)
src/features/activities/upcoming_events/upcoming_event/useUpcomingEvent.tsx (1)

Learnt from: nobodyzero1
PR: #4326
File: src/utils/enrollments.ts:20-25
Timestamp: 2025-07-09T14:24:33.861Z
Learning: In src/utils/enrollments.ts, the enrollmentStartDateChange function already includes a null check for the current variable to handle cases where the find operation returns undefined.

🧬 Code Graph Analysis (6)
src/features/activities/upcoming_events/upcoming_event/useUpcomingEvent.tsx (1)
src/utils/date.ts (1)
  • getDatesBetweenDates (453-470)
src/views/activities/upcoming_events/UpcomingEventDate.tsx (4)
src/views/activities/upcoming_events/index.types.ts (1)
  • UpcomingEventDateProps (34-39)
src/services/i18n/translation.ts (1)
  • generateWeekday (21-33)
src/utils/common.ts (1)
  • getCSSPropertyValue (261-265)
src/utils/date.ts (1)
  • formatDateShortMonth (492-505)
src/views/activities/upcoming_events/UpcomingEventsList.tsx (1)
src/views/activities/upcoming_events/index.types.ts (1)
  • UpcomingEventsListProps (26-28)
src/views/activities/upcoming_events/index.tsx (2)
src/views/activities/upcoming_events/index.types.ts (1)
  • TemplateUpcomingEventsProps (19-24)
src/constants/index.ts (1)
  • LANGUAGE_LIST (31-361)
src/features/activities/upcoming_events/export_upcoming_events/useExportUpcomingEvents.tsx (6)
src/states/settings.ts (4)
  • JWLangLocaleState (209-217)
  • congNameState (28-32)
  • hour24FormatState (104-113)
  • shortDateFormatState (93-102)
src/states/upcoming_events.ts (1)
  • upcomingEventsState (10-16)
src/definition/upcoming_events.ts (1)
  • UpcomingEventType (25-38)
src/views/activities/upcoming_events/index.types.ts (1)
  • TemplateUpcomingEventType (6-17)
src/utils/date.ts (2)
  • formatDate (16-18)
  • getDatesBetweenDates (453-470)
src/services/i18n/translation.ts (1)
  • getMessageByCode (43-45)
src/views/activities/upcoming_events/UpcomingEvent.tsx (2)
src/views/activities/upcoming_events/index.types.ts (1)
  • UpcomingEventProps (30-32)
src/views/activities/upcoming_events/decoration_for_event.tsx (1)
  • decorationsForEvent (20-85)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Code QL
  • GitHub Check: Summary
🔇 Additional comments (9)
src/pages/activities/upcoming_events/index.tsx (2)

9-9: LGTM!

Clean import addition for the new export component.


37-37: LGTM!

The integration of the ExportUpcomingEvents component is well-placed within the admin-only buttons section, replacing the previous placeholder implementation.

src/features/activities/upcoming_events/upcoming_event/useUpcomingEvent.tsx (2)

5-5: LGTM!

Good addition of the utility function import to support the refactored date range logic.


27-30: Excellent refactor using the date utility function.

Replacing the manual date iteration with getDatesBetweenDates improves code maintainability and reduces duplication. The utility function handles the date range generation logic correctly and the useMemo dependencies are properly updated.

src/features/activities/upcoming_events/export_upcoming_events/index.tsx (1)

1-29: Well-structured export component.

The implementation follows React best practices with proper separation of concerns, loading state handling, and consistent styling patterns. The use of the custom hook keeps the component clean and focused on presentation.

src/views/activities/upcoming_events/index.tsx (3)

9-9: LGTM!

Font registration at module level is appropriate for PDF generation setup.


18-20: Good font selection logic with fallback.

The language-based font selection using LANGUAGE_LIST with a fallback to 'Inter' is robust and handles cases where no specific font is configured for a language.


22-36: Well-structured PDF template component.

The component properly composes PDF view elements with appropriate localization, styling, and data passing. The structure is clean and follows the established patterns for PDF document generation.

src/views/activities/upcoming_events/UpcomingEventDate.tsx (1)

15-20: LGTM!

The weekday calculation correctly handles Sunday adjustment from index 0 to 6, properly mapping to the Monday-first weekday array.

Copy link

@rhahao rhahao merged commit b4cf3ff into sws2apps:main Jul 28, 2025
14 checks passed
Copy link

cypress bot commented Jul 28, 2025

organized-app    Run #2980

Run Properties:  status check passed Passed #2980  •  git commit b4cf3ff2d9: feat(views): add pdf template for upcoming events and refactoring
Project organized-app
Branch Review main
Run status status check passed Passed #2980
Run duration 00m 11s
Commit git commit b4cf3ff2d9: feat(views): add pdf template for upcoming events and refactoring
Committer Max Makaluk
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 1
View all changes introduced in this branch ↗︎

@rhahao
Copy link
Member

rhahao commented Jul 29, 2025

🎉 This PR is included in version 3.32.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants