diff --git a/apiserver/apiserver/api/models.py b/apiserver/apiserver/api/models.py index 703eec5..a6ddcda 100644 --- a/apiserver/apiserver/api/models.py +++ b/apiserver/apiserver/api/models.py @@ -59,6 +59,7 @@ class Member(models.Model): monthly_fees = models.IntegerField(default=55, blank=True, null=True) is_allowed_entry = models.BooleanField(default=True) discourse_username = models.CharField(default='', max_length=40, blank=True, null=True) + allow_last_scanned = models.BooleanField(default=True) history = HistoricalRecords(excluded_fields=['member_forms']) diff --git a/apiserver/apiserver/api/views.py b/apiserver/apiserver/api/views.py index a7024fc..9c1d9f7 100644 --- a/apiserver/apiserver/api/views.py +++ b/apiserver/apiserver/api/views.py @@ -119,6 +119,12 @@ class SearchViewSet(Base, Retrieve): elif self.action == 'create' and sort == 'overdue': queryset = queryset.filter(status='Overdue') queryset = queryset.order_by('expire_date') + elif self.action == 'create' and sort == 'last_scanned': + if self.request.user.member.allow_last_scanned: + queryset = queryset.filter(allow_last_scanned=True) + queryset = queryset.order_by('-user__cards__last_seen_at') + else: + queryset = [] elif self.action == 'create' and sort == 'best_looking': queryset = [] diff --git a/webclient/src/Account.js b/webclient/src/Account.js index f858b10..c32f9f5 100644 --- a/webclient/src/Account.js +++ b/webclient/src/Account.js @@ -264,6 +264,16 @@ export function AccountForm(props) { {...makeProps('discourse_username')} />} + + + + + - + {user && isAdmin(user) && diff --git a/webclient/src/Members.js b/webclient/src/Members.js index 356233e..02f4328 100644 --- a/webclient/src/Members.js +++ b/webclient/src/Members.js @@ -11,6 +11,7 @@ import AbortController from 'abort-controller'; const memberSorts = { recently_vetted: 'Recently Vetted', + last_scanned: 'Last Scanned', newest_active: 'Newest', //newest_overall: 'Newest Overall', oldest_active: 'Oldest', @@ -76,7 +77,7 @@ export function Members(props) { const [response, setResponse] = useState(false); const [numShow, setNumShow] = useState(numShowCache); const [controller, setController] = useState(false); - const { token } = props; + const { token, user } = props; const doSearch = (q) => { console.log('doing search', q); @@ -153,44 +154,47 @@ export function Members(props) { {search.length ? 'Search Results' : memberSorts[sort]} - {sort === 'best_looking' ? -
- -
- : - response ? - <> - - {response.results.length ? - response.results.slice(0, numShow).map((x, i) => - -
{i+1}
- - - - - {x.member.preferred_name} {x.member.last_name} - - Status: {x.member.status || 'Unknown'} - Joined: {x.member.application_date || 'Unknown'} - ID: {x.member.id} - -
- ) - : -

No Results

- } -
- - {response.results.length > 20 && numShow !== 100 ? -