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 ?
-