Skip to content

[ResourceApp][Frontend][REFACTOR] Resource Feature Extraction#73

Open
MohamadNazik wants to merge 3 commits intoLSFLK:mainfrom
MohamadNazik:refactor/resource-app-frontend-ddd-resource-feature
Open

[ResourceApp][Frontend][REFACTOR] Resource Feature Extraction#73
MohamadNazik wants to merge 3 commits intoLSFLK:mainfrom
MohamadNazik:refactor/resource-app-frontend-ddd-resource-feature

Conversation

@MohamadNazik
Copy link
Contributor

Context

Part of the incremental DDD refactoring of the resource-app frontend.

What changed

  • Created a dedicated resource feature module with types, constants, API layer, context, hooks, and views
  • Moved resource and stats management out of the global context into a dedicated ResourceProvider
  • Relocated catalog and resource creation views into the resource feature
  • Updated the admin view to consume the resource context directly
  • Cleaned up the root types file to re-export resource types from the resource feature
  • Global AppContext now only manages bookings

Why

The resource entity is the core of this application. Giving it a dedicated feature module with owned views and business logic keeps all resource concerns co-located and removes them from the bloated global context.

Acceptance Criteria

@gemini-code-assist
Copy link

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request implements a significant refactoring of the frontend application by extracting all resource-related logic into a self-contained feature module. This change enhances modularity, improves separation of concerns, and streamlines the global application context, making the codebase more maintainable and scalable. The primary impact is a cleaner architecture where resource management is isolated and independently manageable.

Highlights

  • Resource Feature Module: A new dedicated feature module for resources has been created, encapsulating types, constants, API layer, context, hooks, and views related to resource management.
  • Context Refactoring: Resource and statistics management have been extracted from the global AppContext and moved into a new ResourceProvider, significantly reducing the global context's responsibilities. The AppContext now exclusively handles bookings.
  • View Relocation: The CatalogView and CreateResourceView (formerly views/CreateResourceView) have been relocated into the new features/resource/views directory, aligning them with the dedicated resource feature.
  • Admin View Update: The AdminView has been updated to consume resource-related data and actions directly from the new useResource context instead of the global useApp context.
  • Type Definitions Centralization: The root types.ts file has been cleaned up to re-export resource-specific types from the new features/resource/types module, promoting better organization and preventing duplication.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request does a great job of refactoring the resource management logic into its own dedicated feature module, following DDD principles. The code is well-structured, and the separation of concerns between the AppContext and the new ResourceContext is clear. I've identified a few areas for improvement regarding type safety, key generation, and code maintainability. My detailed comments are below.

- Default new resources to isActive true on creation
- Replace Date.now() with a stable ref counter for form field IDs
- Replace color ternary chains with lookup maps in catalog and creation views
@MohamadNazik MohamadNazik requested a review from a team March 20, 2026 05:11
@MohamadNazik MohamadNazik marked this pull request as draft March 22, 2026 17:15
- Align submit button disabled state with form validation logic
- Surface resource loading and error states in the global app shell
- Add safe fallback for specs to prevent crash on missing data
- Make reschedule inputs controlled and reset state on modal close
- Clear reschedule time state when opening the propose time modal
@MohamadNazik MohamadNazik requested a review from ginaxu1 March 22, 2026 17:33
@MohamadNazik MohamadNazik marked this pull request as ready for review March 22, 2026 17:33

const handleAddField = () => {
setFormFields(prevFields => [...prevFields, {
id: `field_${fieldIdCounter.current++}`,
Copy link

Choose a reason for hiding this comment

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

why not use more robust id generation method like crypto.randomUUID() ?

issue here is if a user edits an existing resource that already has fields named field_0, field_1, etc., adding a new field will restart the counter at 0 and result in duplicate React keys and duplicate ids in the payload

setResources(prev => [...prev, res.data!]);
return true;
}
return false;
Copy link

@ginaxu1 ginaxu1 Mar 23, 2026

Choose a reason for hiding this comment

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

currently addResource and updateResource return false if error. then handleSubmit in useResourceForm.ts sees success = false and sets isSubmitting to false, but never triggers an error message or UI feedback. The user is left clicking a button that appears to do nothing

Better to include error in result here

interface MutationResult {
  success: boolean;
  error?: string;
}

interface ResourceContextType {
  // ... keep existing properties
  addResource: (data: Omit<Resource, 'id'>) => Promise<MutationResult>;
  updateResource: (data: Resource) => Promise<MutationResult>;
  // ... 
}

Copy link

Choose a reason for hiding this comment

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

this way ResourceProvider can be updated as such:

const addResource = useCallback(async (data: Omit<Resource, 'id'>) => {
    const res = await resourceApi.addResource(data);
    if (res.success && res.data) {
      setResources(prev => [...prev, res.data!]);
      return { success: true };
    }
    return { success: false, error: res.error || 'Failed to add resource' };
  }, []);

  const updateResource = useCallback(async (data: Resource) => {
    const res = await resourceApi.updateResource(data);
    if (res.success && res.data) {
      setResources(prev => prev.map(r => r.id === data.id ? res.data! : r));
      return { success: true };
    }
    return { success: false, error: res.error || 'Failed to update resource' };
  }, []);

}

setIsSubmitting(false);
if (success) onClose();
Copy link

@ginaxu1 ginaxu1 Mar 23, 2026

Choose a reason for hiding this comment

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

If you made the updates to addResource and updateResource above, then above handleSubmit function, you should add: const [submitError, setSubmitError] = useState<string | null>(null);

And within handleSubmit, change this last part to

if (result.success) {
    onClose();
  } else {
    setSubmitError(result.error || 'An unexpected error occurred.');
  }

Copy link

Choose a reason for hiding this comment

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

Finally, in features/resource/views/CreateResourceView.tsx

you can get submitError from the hook

  const {
    isSubmitting,
    submitError, // <-- Extract the error
    basicInfo, setBasicInfo,
    // ...
  } = useResourceForm(onClose, initialData);

And display it in the UI above the submit button, for example:

        {submitError && (
          <div className="p-3 bg-red-50 text-red-600 text-sm rounded-lg border border-red-100 flex items-center gap-2">
            <span className="font-semibold">Error:</span> {submitError}
          </div>
        )}

        <Button .... /> 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ResourceApp][Frontend][REFACTOR] Introduce Resource domain with context, API layer, and owned views

2 participants