Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor users table and pagination #381

Open
wants to merge 2 commits into
base: filip-refactor-user-module
Choose a base branch
from

Conversation

sodic
Copy link
Collaborator

@sodic sodic commented Feb 21, 2025

No description provided.

@sodic sodic changed the base branch from main to filip-refactor-user-module February 21, 2025 13:08
Comment on lines 136 to 138
<option value='both'>both</option>
<option value='true'>true</option>
<option value='false'>false</option>
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

How come this dropdown doesn't use the SVG, while the other one does?

@@ -113,8 +103,8 @@ const UsersTable = () => {
className='absolute top-0 left-0 z-20 h-full w-full bg-white opacity-0'
>
<option value=''>Select filters</option>
{['past_due', 'canceled', 'active', 'deleted', null].map((status) => {
if (!statusOptions.includes(status as SubscriptionStatus)) {
{['past_due', 'cancel_at_period_end', 'active', 'deleted', null].map((status) => {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think this was a mistake, the filtered returned nothing.

I'm guessing canceled is an old status.

Comment on lines +150 to +153
const value = parseInt(e.currentTarget.value);
if (data?.totalPages && value <= data?.totalPages && value > 0) {
setCurrentPage(value);
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The old code had a bug and would break if you manually deleted the page number.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm guessing you mean "manually edited"?

@@ -88,41 +95,18 @@ export const getPaginatedUsers: GetPaginatedUsers<GetPaginatedUsersInput, GetPag
paymentProcessorUserId: true,
},
orderBy: {
id: 'desc',
username: 'asc',
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sorting seems less random because users are displayed in the table.

Comment on lines +26 to +31
skipPages: number;
filter: {
emailContains?: string;
isAdmin?: boolean;
subscriptionStatusIn?: SubscriptionStatus[];
};
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Separating the data (filter params) from the metadata (paging params).

@sodic sodic marked this pull request as ready for review February 21, 2025 13:35
@sodic sodic requested review from vincanger and infomiho February 21, 2025 14:04
const [page, setPage] = useState(1);
const [email, setEmail] = useState<string | undefined>(undefined);
const [currentPage, setCurrentPage] = useState(1);
const [emailFilter, setEmailFilter] = useState<string>('');
Copy link
Collaborator

Choose a reason for hiding this comment

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

If we have undefined for isAdmin as empty state, I'd expect it to have for the emailFilter as well.

Below you are counting on the behavior when emailFilter is fasly anyways (emailFilter &&) - you could go all the way with explicit undefined.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Okay, I guess it's because of setEmailFilter(e.currentTarget.value);, okay this looks like it's more justified. But in the name of consistency, maybe you could go for:

if (e.currentTarget.value === '') {
setEmailFilter(undefined);
} else {
setEmailFilter(e.currentTarget.value);
}

filter: {
...(emailFilter && { emailContains: emailFilter }),
...(isAdminFilter !== undefined && { isAdmin: isAdminFilter }),
...(subscriptionStatusFilter?.length > 0 && { subscriptionStatusIn: subscriptionStatusFilter }),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can subscriptionStatusFilter ever be undefined or null?

Comment on lines +31 to +36
useEffect(
function backToPageOne() {
setCurrentPage(1);
},
[emailFilter, subscriptionStatusFilter, isAdminFilter]
);
Copy link
Collaborator

Choose a reason for hiding this comment

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

For some reason, this, to me, feels like an odd way of writing it (I'm not saying it's wrong), I'd write something like this:

  function backToPageOne() {
    setCurrentPage(1);
  },
  useEffect(() => {
    backToPageOne();
  }, [emailFilter, subscriptionStatusFilter, isAdminFilter]);

Copy link
Collaborator Author

@sodic sodic Feb 21, 2025

Choose a reason for hiding this comment

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

I only learned about this trick recently. I like it because it allows you to name your inline useEffect function without forcing you to jump around with your eyes - you still read it sequentially, but can now tell what it's supposed to do.

Also, the anonymous useEffect arrow function that wraps backToPageOne can easily grow and include more logic, and then we're back at square one - an anonymous inline function

The only thing I don't like is the formatting. This is how I'd like it to look:

useEffect(function backToPageOne() {
  setCurrentPage(1);
}, [emailFilter, subscriptionStatusFilter, isAdminFilter]);

But prettier doesn't allow it.

Regardless of the formatting, I still like this trick above reasons. That said, if you think it's weird enough to throw people off, I'll change it.

Btw, this isn't supposed to be a useEffect anyway - we should be calling backToPageOne on each filter change, but I didn't have time to refactor that.

@@ -56,8 +59,8 @@ const UsersTable = () => {
</label>
<div className='flex-grow relative z-20 rounded border border-stroke pr-8 outline-none bg-white transition focus:border-primary active:border-primary dark:border-form-strokedark dark:bg-form-input'>
<div className='flex items-center'>
{!!statusOptions && statusOptions.length > 0 ? (
statusOptions.map((opt) => (
{!!subscriptionStatusFilter && subscriptionStatusFilter.length > 0 ? (
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd drop the !!subscriptionStatusFilter here since it can't be undefined or null.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, this is old, the change is included because of formatting.

I'll fix it up.

Copy link
Collaborator

@infomiho infomiho left a comment

Choose a reason for hiding this comment

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

Some minor suggestions

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.

2 participants