Skip to content

Commit c167f5e

Browse files
Merge pull request #3848 from codecrafters-io/revert/team-members-cleanup
Revert team members table changes, keep Last Seen sorting
2 parents d2567f5 + 9076b60 commit c167f5e

12 files changed

Lines changed: 62 additions & 312 deletions

File tree

Lines changed: 51 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -1,154 +1,57 @@
1-
{{#if @enablePeriodFilter}}
2-
<TeamPage::Section @title="Team Members" ...attributes>
3-
<:headerRight>
4-
<div class="flex items-center gap-2 text-sm text-gray-500" data-test-period-filter>
5-
<span>View activity within</span>
6-
<div class="relative">
7-
<button
8-
type="button"
9-
class="inline-flex items-center gap-1 px-3 py-1.5 border border-gray-300 rounded-md bg-white text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-teal-500 focus:ring-offset-1"
10-
data-test-period-toggle
11-
{{on "click" this.togglePeriodDropdown}}
1+
<TeamPage::Section @title="Team Members" ...attributes>
2+
<div class="overflow-x-auto -mx-4 md:-mx-6">
3+
<table class="min-w-full">
4+
<thead>
5+
<tr class="border-b border-gray-200">
6+
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Member</th>
7+
<th
8+
role="button"
9+
class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:text-gray-700 select-none"
10+
{{on "click" this.handleLastSeenSortClick}}
11+
data-test-sort-header="lastSeen"
1212
>
13-
{{this.selectedPeriodLabel}}
14-
<svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
15-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
16-
</svg>
17-
</button>
18-
{{#if this.isPeriodDropdownOpen}}
19-
<div class="fixed inset-0 z-[5]" {{on "click" this.closePeriodDropdown}}></div>
20-
<div
21-
class="absolute right-0 mt-1 w-32 bg-white border border-gray-200 rounded-md shadow-lg z-10"
22-
data-test-period-dropdown
23-
>
24-
{{#each this.periodOptions as |option|}}
25-
<button
26-
type="button"
27-
class="w-full text-left px-3 py-2 text-sm hover:bg-gray-50 {{if (eq option.value this.selectedPeriod) 'text-teal-600 font-medium' 'text-gray-700'}}"
28-
data-test-period-option={{option.value}}
29-
{{on "click" (fn this.handlePeriodSelect option.value)}}
30-
>
31-
{{option.label}}
32-
</button>
33-
{{/each}}
34-
</div>
35-
{{/if}}
36-
</div>
37-
</div>
38-
</:headerRight>
39-
40-
<:default>
41-
<div class="overflow-x-auto -mx-4 md:-mx-6">
42-
<table class="min-w-full">
43-
<thead>
44-
<tr class="border-b border-gray-200">
45-
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Member</th>
46-
<th
47-
class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:text-gray-700 select-none"
48-
{{on "click" this.handleLastSeenSortClick}}
49-
data-test-sort-header="lastSeen"
50-
>
51-
<span class="inline-flex items-center gap-1">
52-
Last Seen
53-
{{#if this.lastSeenSortDirection}}
54-
<svg class="w-3 h-3 {{if (eq this.lastSeenSortDirection 'asc') '' 'rotate-180'}}" fill="currentColor" viewBox="0 0 20 20">
55-
<path fill-rule="evenodd" d="M5.293 7.707a1 1 0 010-1.414l4-4a1 1 0 011.414 0l4 4a1 1 0 01-1.414 1.414L10 4.414l-3.293 3.293a1 1 0 01-1.414 0z" clip-rule="evenodd"></path>
56-
</svg>
57-
{{/if}}
58-
</span>
59-
</th>
60-
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Joined</th>
61-
<th class="px-3 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">Attempts</th>
62-
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Courses</th>
63-
<th class="px-3 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider"></th>
64-
</tr>
65-
</thead>
66-
<tbody>
67-
{{#each this.sortedMemberships as |membership|}}
68-
<TeamPage::MembersTable::Row
69-
@membership={{membership}}
70-
@currentUserIsTeamAdmin={{this.currentUserIsTeamAdmin}}
71-
@attempts={{this.getAttempts membership}}
72-
/>
73-
{{/each}}
74-
</tbody>
75-
</table>
76-
</div>
77-
78-
<div class="mt-6">
79-
<div class="inline-flex border-b border-teal-500 uppercase text-teal-500 font-bold text-sm mb-4">
80-
Invite URL
81-
</div>
82-
83-
{{#if this.currentUserIsTeamAdmin}}
84-
<div class="mb-3 text-gray-600 text-sm" data-test-invite-url-description>
85-
To invite new members, send them this invite URL.
86-
</div>
13+
<span class="inline-flex items-center gap-1">
14+
Last Seen
15+
{{#if this.lastSeenSortDirection}}
16+
<svg class="w-3 h-3 {{if (eq this.lastSeenSortDirection 'asc') '' 'rotate-180'}}" fill="currentColor" viewBox="0 0 20 20">
17+
<path
18+
fill-rule="evenodd"
19+
d="M5.293 7.707a1 1 0 010-1.414l4-4a1 1 0 011.414 0l4 4a1 1 0 01-1.414 1.414L10 4.414l-3.293 3.293a1 1 0 01-1.414 0z"
20+
clip-rule="evenodd"
21+
></path>
22+
</svg>
23+
{{/if}}
24+
</span>
25+
</th>
26+
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Joined</th>
27+
<th class="px-3 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">Stages</th>
28+
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Courses</th>
29+
<th class="px-3 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider"></th>
30+
</tr>
31+
</thead>
32+
<tbody>
33+
{{#each this.sortedMemberships as |membership|}}
34+
<TeamPage::MembersTable::Row @membership={{membership}} @currentUserIsTeamAdmin={{this.currentUserIsTeamAdmin}} />
35+
{{/each}}
36+
</tbody>
37+
</table>
38+
</div>
8739

88-
<CopyableCode @code="{{@team.inviteUrl}}" />
89-
{{else}}
90-
<div class="text-gray-600 text-sm" data-test-invite-url-description>
91-
To invite new members, ask one of the team admins for an invite URL.
92-
</div>
93-
{{/if}}
94-
</div>
95-
</:default>
96-
</TeamPage::Section>
97-
{{else}}
98-
<TeamPage::Section @title="Team Members" ...attributes>
99-
<div class="overflow-x-auto -mx-4 md:-mx-6">
100-
<table class="min-w-full">
101-
<thead>
102-
<tr class="border-b border-gray-200">
103-
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Member</th>
104-
<th
105-
class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:text-gray-700 select-none"
106-
{{on "click" this.handleLastSeenSortClick}}
107-
data-test-sort-header="lastSeen"
108-
>
109-
<span class="inline-flex items-center gap-1">
110-
Last Seen
111-
{{#if this.lastSeenSortDirection}}
112-
<svg class="w-3 h-3 {{if (eq this.lastSeenSortDirection 'asc') '' 'rotate-180'}}" fill="currentColor" viewBox="0 0 20 20">
113-
<path fill-rule="evenodd" d="M5.293 7.707a1 1 0 010-1.414l4-4a1 1 0 011.414 0l4 4a1 1 0 01-1.414 1.414L10 4.414l-3.293 3.293a1 1 0 01-1.414 0z" clip-rule="evenodd"></path>
114-
</svg>
115-
{{/if}}
116-
</span>
117-
</th>
118-
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Joined</th>
119-
<th class="px-3 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">Attempts</th>
120-
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Courses</th>
121-
<th class="px-3 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider"></th>
122-
</tr>
123-
</thead>
124-
<tbody>
125-
{{#each this.sortedMemberships as |membership|}}
126-
<TeamPage::MembersTable::Row
127-
@membership={{membership}}
128-
@currentUserIsTeamAdmin={{this.currentUserIsTeamAdmin}}
129-
@attempts={{this.getAttempts membership}}
130-
/>
131-
{{/each}}
132-
</tbody>
133-
</table>
40+
<div class="mt-6">
41+
<div class="inline-flex border-b border-teal-500 uppercase text-teal-500 font-bold text-sm mb-4">
42+
Invite URL
13443
</div>
13544

136-
<div class="mt-6">
137-
<div class="inline-flex border-b border-teal-500 uppercase text-teal-500 font-bold text-sm mb-4">
138-
Invite URL
45+
{{#if this.currentUserIsTeamAdmin}}
46+
<div class="mb-3 text-gray-600 text-sm" data-test-invite-url-description>
47+
To invite new members, send them this invite URL.
13948
</div>
14049

141-
{{#if this.currentUserIsTeamAdmin}}
142-
<div class="mb-3 text-gray-600 text-sm" data-test-invite-url-description>
143-
To invite new members, send them this invite URL.
144-
</div>
145-
146-
<CopyableCode @code="{{@team.inviteUrl}}" />
147-
{{else}}
148-
<div class="text-gray-600 text-sm" data-test-invite-url-description>
149-
To invite new members, ask one of the team admins for an invite URL.
150-
</div>
151-
{{/if}}
152-
</div>
153-
</TeamPage::Section>
154-
{{/if}}
50+
<CopyableCode @code="{{@team.inviteUrl}}" />
51+
{{else}}
52+
<div class="text-gray-600 text-sm" data-test-invite-url-description>
53+
To invite new members, ask one of the team admins for an invite URL.
54+
</div>
55+
{{/if}}
56+
</div>
57+
</TeamPage::Section>

app/components/team-page/members-table.ts

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,20 @@ import type AuthenticatorService from 'codecrafters-frontend/services/authentica
66
import type TeamModel from 'codecrafters-frontend/models/team';
77
import type TeamMembershipModel from 'codecrafters-frontend/models/team-membership';
88

9-
type TimePeriod = 'all' | '3m' | '6m' | '1y';
109
type SortDirection = 'asc' | 'desc';
1110

12-
const PERIOD_OPTIONS: { value: TimePeriod; label: string }[] = [
13-
{ value: 'all', label: 'All time' },
14-
{ value: '3m', label: '3 months' },
15-
{ value: '6m', label: '6 months' },
16-
{ value: '1y', label: '1 year' },
17-
];
18-
1911
interface Signature {
2012
Element: HTMLDivElement;
2113

2214
Args: {
2315
team: TeamModel;
24-
enablePeriodFilter: boolean;
2516
};
2617
}
2718

2819
export default class TeamPageMembersTable extends Component<Signature> {
2920
@service declare authenticator: AuthenticatorService;
3021

31-
@tracked selectedPeriod: TimePeriod = 'all';
3222
@tracked lastSeenSortDirection: SortDirection | null = null;
33-
@tracked isPeriodDropdownOpen = false;
34-
35-
periodOptions = PERIOD_OPTIONS;
3623

3724
get currentUserIsTeamAdmin() {
3825
if (!this.authenticator.currentUser) {
@@ -42,24 +29,6 @@ export default class TeamPageMembersTable extends Component<Signature> {
4229
return this.args.team.admins.includes(this.authenticator.currentUser);
4330
}
4431

45-
get selectedPeriodLabel(): string {
46-
return PERIOD_OPTIONS.find((o) => o.value === this.selectedPeriod)!.label;
47-
}
48-
49-
@action
50-
getAttempts(membership: TeamMembershipModel): number {
51-
switch (this.selectedPeriod) {
52-
case '3m':
53-
return membership.numberOfAttempts3m || 0;
54-
case '6m':
55-
return membership.numberOfAttempts6m || 0;
56-
case '1y':
57-
return membership.numberOfAttempts1y || 0;
58-
default:
59-
return membership.numberOfStageAttempts || 0;
60-
}
61-
}
62-
6332
get sortedMemberships(): TeamMembershipModel[] {
6433
const memberships = this.args.team.memberships.slice();
6534

@@ -104,22 +73,6 @@ export default class TeamPageMembersTable extends Component<Signature> {
10473
this.lastSeenSortDirection = 'desc';
10574
}
10675
}
107-
108-
@action
109-
handlePeriodSelect(period: TimePeriod) {
110-
this.selectedPeriod = period;
111-
this.isPeriodDropdownOpen = false;
112-
}
113-
114-
@action
115-
togglePeriodDropdown() {
116-
this.isPeriodDropdownOpen = !this.isPeriodDropdownOpen;
117-
}
118-
119-
@action
120-
closePeriodDropdown() {
121-
this.isPeriodDropdownOpen = false;
122-
}
12376
}
12477

12578
declare module '@glint/environment-ember-loose/registry' {

app/components/team-page/members-table/row.hbs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@
4747
{{short-relative-time @membership.createdAt}}
4848
</td>
4949

50-
{{! Attempts column }}
51-
<td class="px-3 py-3 text-right text-gray-700 text-sm font-mono" data-test-attempts>
52-
{{@attempts}}
50+
{{! Stages column }}
51+
<td class="px-3 py-3 text-right text-gray-700 text-sm font-mono">
52+
{{@membership.numberOfStageAttempts}}
5353
</td>
5454

5555
{{! Courses column — scrollable, max ~4 icons wide with fade }}
@@ -107,4 +107,4 @@
107107
{{/if}}
108108
{{/unless}}
109109
</td>
110-
</tr>
110+
</tr>

app/components/team-page/members-table/row.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ interface Signature {
1616
Args: {
1717
membership: TeamMembershipModel;
1818
currentUserIsTeamAdmin: boolean;
19-
attempts: number;
2019
};
2120
}
2221

app/components/team-page/section.hbs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
<div class="bg-white p-4 md:p-6 rounded-sm border border-gray-200" ...attributes>
2-
<div class="mb-4 flex items-center justify-between">
2+
<div class="mb-4">
33
<div class="inline-flex border-b border-teal-500 uppercase text-teal-500 font-bold text-sm">
44
{{@title}}
55
</div>
6-
{{#if (has-block "headerRight")}}
7-
{{yield to="headerRight"}}
8-
{{/if}}
96
</div>
107

118
{{yield}}

app/components/team-page/section.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ interface Signature {
99

1010
Blocks: {
1111
default: [];
12-
headerRight: [];
1312
};
1413
}
1514

app/controllers/team.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,4 @@ import type { ModelType } from 'codecrafters-frontend/routes/team';
33

44
export default class TeamController extends Controller {
55
declare model: ModelType;
6-
7-
queryParams = ['q'];
8-
q: string | null = null;
96
}

app/models/team-membership.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,6 @@ export default class TeamMembershipModel extends Model {
1111
@attr('number') declare numberOfStageAttempts: number;
1212
@attr('date') declare lastAttemptAt: Date | null;
1313

14-
@attr('number') declare numberOfAttempts: number;
15-
@attr('number') declare numberOfStagesCompleted: number;
16-
@attr('number') declare numberOfAttempts3m: number;
17-
@attr('number') declare numberOfAttempts6m: number;
18-
@attr('number') declare numberOfAttempts1y: number;
19-
@attr('number') declare numberOfStagesCompleted3m: number;
20-
@attr('number') declare numberOfStagesCompleted6m: number;
21-
@attr('number') declare numberOfStagesCompleted1y: number;
22-
2314
get isSoleAdmin(): boolean {
2415
return this.team.admins.length === 1 && this.isAdmin;
2516
}

app/templates/team.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@
1919
<TeamPage::SlackIntegrationSettingsContainer @team={{this.model.team}} class="mt-4" />
2020
</div>
2121

22-
<TeamPage::MembersTable @team={{this.model.team}} @enablePeriodFilter={{(eq this.q "v2")}} class="w-full md:w-3/4" />
22+
<TeamPage::MembersTable @team={{this.model.team}} class="w-full md:w-3/4" />
2323
</div>
2424
</div>

0 commit comments

Comments
 (0)