Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
281 changes: 144 additions & 137 deletions app/components/team-page/members-table.hbs
Original file line number Diff line number Diff line change
@@ -1,147 +1,154 @@
<TeamPage::Section @title="Team Members" ...attributes>
<:headerRight>
<div class="flex items-center gap-2 text-sm text-gray-500" data-test-period-filter>
<span>View activity within</span>
<div class="relative">
<button
type="button"
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"
data-test-period-toggle
{{on "click" this.togglePeriodDropdown}}
>
{{this.selectedPeriodLabel}}
<svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
</svg>
</button>
{{#if this.isPeriodDropdownOpen}}
<div class="fixed inset-0 z-[5]" {{on "click" this.closePeriodDropdown}}></div>
<div
class="absolute right-0 mt-1 w-32 bg-white border border-gray-200 rounded-md shadow-lg z-10"
data-test-period-dropdown
{{#if @enablePeriodFilter}}
<TeamPage::Section @title="Team Members" ...attributes>
<:headerRight>
<div class="flex items-center gap-2 text-sm text-gray-500" data-test-period-filter>
<span>View activity within</span>
<div class="relative">
<button
type="button"
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"
data-test-period-toggle
{{on "click" this.togglePeriodDropdown}}
>
{{#each this.periodOptions as |option|}}
<button
type="button"
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'}}"
data-test-period-option={{option.value}}
{{on "click" (fn this.handlePeriodSelect option.value)}}
{{this.selectedPeriodLabel}}
<svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
</svg>
</button>
{{#if this.isPeriodDropdownOpen}}
<div class="fixed inset-0 z-[5]" {{on "click" this.closePeriodDropdown}}></div>
<div
class="absolute right-0 mt-1 w-32 bg-white border border-gray-200 rounded-md shadow-lg z-10"
data-test-period-dropdown
>
{{#each this.periodOptions as |option|}}
<button
type="button"
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'}}"
data-test-period-option={{option.value}}
{{on "click" (fn this.handlePeriodSelect option.value)}}
>
{{option.label}}
</button>
{{/each}}
</div>
{{/if}}
</div>
</div>
</:headerRight>

<:default>
<div class="overflow-x-auto -mx-4 md:-mx-6">
<table class="min-w-full">
<thead>
<tr class="border-b border-gray-200">
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Member</th>
<th
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"
{{on "click" this.handleLastSeenSortClick}}
data-test-sort-header="lastSeen"
>
{{option.label}}
</button>
<span class="inline-flex items-center gap-1">
Last Seen
{{#if this.lastSeenSortDirection}}
<svg class="w-3 h-3 {{if (eq this.lastSeenSortDirection 'asc') '' 'rotate-180'}}" fill="currentColor" viewBox="0 0 20 20">
<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>
</svg>
{{/if}}
</span>
</th>
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Joined</th>
<th class="px-3 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">Attempts</th>
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Courses</th>
<th class="px-3 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider"></th>
</tr>
</thead>
<tbody>
{{#each this.sortedMemberships as |membership|}}
<TeamPage::MembersTable::Row
@membership={{membership}}
@currentUserIsTeamAdmin={{this.currentUserIsTeamAdmin}}
@attempts={{this.getAttempts membership}}
/>
{{/each}}
</div>
{{/if}}
</tbody>
</table>
</div>
</div>
</:headerRight>

<:default>
<div class="overflow-x-auto -mx-4 md:-mx-6">
<table class="min-w-full">
<thead>
<tr class="border-b border-gray-200">
<th
class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:text-gray-700 select-none"
{{on "click" (fn this.handleSortClick "member")}}
data-test-sort-header="member"
>
<span class="inline-flex items-center gap-1">
Member
{{#if (eq this.sortColumn "member")}}
<svg class="w-3 h-3 {{if (eq this.sortDirection 'asc') '' 'rotate-180'}}" fill="currentColor" viewBox="0 0 20 20">
<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>
</svg>
{{/if}}
</span>
</th>
<th
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"
{{on "click" (fn this.handleSortClick "lastSeen")}}
data-test-sort-header="lastSeen"
>
<span class="inline-flex items-center gap-1">
Last Seen
{{#if (eq this.sortColumn "lastSeen")}}
<svg class="w-3 h-3 {{if (eq this.sortDirection 'asc') '' 'rotate-180'}}" fill="currentColor" viewBox="0 0 20 20">
<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>
</svg>
{{/if}}
</span>
</th>
<th
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"
{{on "click" (fn this.handleSortClick "joined")}}
data-test-sort-header="joined"
>
<span class="inline-flex items-center gap-1">
Joined
{{#if (eq this.sortColumn "joined")}}
<svg class="w-3 h-3 {{if (eq this.sortDirection 'asc') '' 'rotate-180'}}" fill="currentColor" viewBox="0 0 20 20">
<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>
</svg>
{{/if}}
</span>
</th>
<th
class="px-3 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider cursor-pointer hover:text-gray-700 select-none"
{{on "click" (fn this.handleSortClick "attempts")}}
data-test-sort-header="attempts"
>
<span class="inline-flex items-center gap-1 justify-end">
Attempts
{{#if (eq this.sortColumn "attempts")}}
<svg class="w-3 h-3 {{if (eq this.sortDirection 'asc') '' 'rotate-180'}}" fill="currentColor" viewBox="0 0 20 20">
<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>
</svg>
{{/if}}
</span>
</th>
<th
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"
{{on "click" (fn this.handleSortClick "courses")}}
data-test-sort-header="courses"
>
<span class="inline-flex items-center gap-1">
Courses
{{#if (eq this.sortColumn "courses")}}
<svg class="w-3 h-3 {{if (eq this.sortDirection 'asc') '' 'rotate-180'}}" fill="currentColor" viewBox="0 0 20 20">
<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>
</svg>
{{/if}}
</span>
</th>
<th class="px-3 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider"></th>
</tr>
</thead>
<tbody>
{{#each this.sortedMemberships as |membership|}}
<TeamPage::MembersTable::Row
@membership={{membership}}
@currentUserIsTeamAdmin={{this.currentUserIsTeamAdmin}}
@attempts={{this.getAttempts membership}}
/>
{{/each}}
</tbody>
</table>
</div>
<div class="mt-6">
<div class="inline-flex border-b border-teal-500 uppercase text-teal-500 font-bold text-sm mb-4">
Invite URL
</div>

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

{{#if this.currentUserIsTeamAdmin}}
<div class="mb-3 text-gray-600 text-sm" data-test-invite-url-description>
To invite new members, send them this invite URL.
<CopyableCode @code="{{@team.inviteUrl}}" />
{{else}}
<div class="text-gray-600 text-sm" data-test-invite-url-description>
To invite new members, ask one of the team admins for an invite URL.
</div>
{{/if}}
</div>
</:default>
</TeamPage::Section>
{{else}}
<TeamPage::Section @title="Team Members" ...attributes>
<div class="overflow-x-auto -mx-4 md:-mx-6">
<table class="min-w-full">
<thead>
<tr class="border-b border-gray-200">
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Member</th>
<th
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"
{{on "click" this.handleLastSeenSortClick}}
data-test-sort-header="lastSeen"
>
<span class="inline-flex items-center gap-1">
Last Seen
{{#if this.lastSeenSortDirection}}
<svg class="w-3 h-3 {{if (eq this.lastSeenSortDirection 'asc') '' 'rotate-180'}}" fill="currentColor" viewBox="0 0 20 20">
<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>
</svg>
{{/if}}
</span>
</th>
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Joined</th>
<th class="px-3 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">Attempts</th>
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Courses</th>
<th class="px-3 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider"></th>
</tr>
</thead>
<tbody>
{{#each this.sortedMemberships as |membership|}}
<TeamPage::MembersTable::Row
@membership={{membership}}
@currentUserIsTeamAdmin={{this.currentUserIsTeamAdmin}}
@attempts={{this.getAttempts membership}}
/>
{{/each}}
</tbody>
</table>
</div>

<CopyableCode @code="{{@team.inviteUrl}}" />
{{else}}
<div class="text-gray-600 text-sm" data-test-invite-url-description>
To invite new members, ask one of the team admins for an invite URL.
<div class="mt-6">
<div class="inline-flex border-b border-teal-500 uppercase text-teal-500 font-bold text-sm mb-4">
Invite URL
</div>
{{/if}}
</div>
</:default>
</TeamPage::Section>

{{#if this.currentUserIsTeamAdmin}}
<div class="mb-3 text-gray-600 text-sm" data-test-invite-url-description>
To invite new members, send them this invite URL.
</div>

<CopyableCode @code="{{@team.inviteUrl}}" />
{{else}}
<div class="text-gray-600 text-sm" data-test-invite-url-description>
To invite new members, ask one of the team admins for an invite URL.
</div>
{{/if}}
</div>
</TeamPage::Section>
{{/if}}
Loading
Loading