Allow sorting by Last Scanned
This commit is contained in:
parent
66784c457a
commit
e511723c07
|
@ -59,6 +59,7 @@ class Member(models.Model):
|
||||||
monthly_fees = models.IntegerField(default=55, blank=True, null=True)
|
monthly_fees = models.IntegerField(default=55, blank=True, null=True)
|
||||||
is_allowed_entry = models.BooleanField(default=True)
|
is_allowed_entry = models.BooleanField(default=True)
|
||||||
discourse_username = models.CharField(default='', max_length=40, blank=True, null=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'])
|
history = HistoricalRecords(excluded_fields=['member_forms'])
|
||||||
|
|
||||||
|
|
|
@ -119,6 +119,12 @@ class SearchViewSet(Base, Retrieve):
|
||||||
elif self.action == 'create' and sort == 'overdue':
|
elif self.action == 'create' and sort == 'overdue':
|
||||||
queryset = queryset.filter(status='Overdue')
|
queryset = queryset.filter(status='Overdue')
|
||||||
queryset = queryset.order_by('expire_date')
|
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':
|
elif self.action == 'create' and sort == 'best_looking':
|
||||||
queryset = []
|
queryset = []
|
||||||
|
|
||||||
|
|
|
@ -264,6 +264,16 @@ export function AccountForm(props) {
|
||||||
{...makeProps('discourse_username')}
|
{...makeProps('discourse_username')}
|
||||||
/>}
|
/>}
|
||||||
|
|
||||||
|
<Form.Field>
|
||||||
|
<label>Participate in "Last Scanned" member list?</label>
|
||||||
|
<Checkbox
|
||||||
|
label='Yes, show me'
|
||||||
|
name='allow_last_scanned'
|
||||||
|
onChange={handleCheck}
|
||||||
|
checked={input.allow_last_scanned}
|
||||||
|
/>
|
||||||
|
</Form.Field>
|
||||||
|
|
||||||
<Form.Input
|
<Form.Input
|
||||||
label='Member Photo'
|
label='Member Photo'
|
||||||
name='photo'
|
name='photo'
|
||||||
|
|
|
@ -274,7 +274,7 @@ function App() {
|
||||||
<MemberDetail token={token} user={user} />
|
<MemberDetail token={token} user={user} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path='/members'>
|
<Route path='/members'>
|
||||||
<Members token={token} />
|
<Members token={token} user={user} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
{user && isAdmin(user) &&
|
{user && isAdmin(user) &&
|
||||||
|
|
|
@ -11,6 +11,7 @@ import AbortController from 'abort-controller';
|
||||||
|
|
||||||
const memberSorts = {
|
const memberSorts = {
|
||||||
recently_vetted: 'Recently Vetted',
|
recently_vetted: 'Recently Vetted',
|
||||||
|
last_scanned: 'Last Scanned',
|
||||||
newest_active: 'Newest',
|
newest_active: 'Newest',
|
||||||
//newest_overall: 'Newest Overall',
|
//newest_overall: 'Newest Overall',
|
||||||
oldest_active: 'Oldest',
|
oldest_active: 'Oldest',
|
||||||
|
@ -76,7 +77,7 @@ export function Members(props) {
|
||||||
const [response, setResponse] = useState(false);
|
const [response, setResponse] = useState(false);
|
||||||
const [numShow, setNumShow] = useState(numShowCache);
|
const [numShow, setNumShow] = useState(numShowCache);
|
||||||
const [controller, setController] = useState(false);
|
const [controller, setController] = useState(false);
|
||||||
const { token } = props;
|
const { token, user } = props;
|
||||||
|
|
||||||
const doSearch = (q) => {
|
const doSearch = (q) => {
|
||||||
console.log('doing search', q);
|
console.log('doing search', q);
|
||||||
|
@ -153,44 +154,47 @@ export function Members(props) {
|
||||||
{search.length ? 'Search Results' : memberSorts[sort]}
|
{search.length ? 'Search Results' : memberSorts[sort]}
|
||||||
</Header>
|
</Header>
|
||||||
|
|
||||||
{sort === 'best_looking' ?
|
{sort === 'last_scanned' &&
|
||||||
<center>
|
(user.member.allow_last_scanned ?
|
||||||
<img className='bean' src='/mr-bean.jpg' />
|
<p>Hide yourself from this list on the <Link to='/account'>Account Settings</Link> page.</p>
|
||||||
</center>
|
|
||||||
:
|
|
||||||
response ?
|
|
||||||
<>
|
|
||||||
<Item.Group unstackable divided>
|
|
||||||
{response.results.length ?
|
|
||||||
response.results.slice(0, numShow).map((x, i) =>
|
|
||||||
<Item key={x.member.id} as={Link} to={'/members/'+x.member.id}>
|
|
||||||
<div className='list-num'>{i+1}</div>
|
|
||||||
<Item.Image size='tiny' src={x.member.photo_small ? staticUrl + '/' + x.member.photo_small : '/nophoto.png'} />
|
|
||||||
<Item.Content verticalAlign='top'>
|
|
||||||
<Item.Header>
|
|
||||||
<Icon name='circle' color={statusColor[x.member.status]} />
|
|
||||||
{x.member.preferred_name} {x.member.last_name}
|
|
||||||
</Item.Header>
|
|
||||||
<Item.Description>Status: {x.member.status || 'Unknown'}</Item.Description>
|
|
||||||
<Item.Description>Joined: {x.member.application_date || 'Unknown'}</Item.Description>
|
|
||||||
<Item.Description>ID: {x.member.id}</Item.Description>
|
|
||||||
</Item.Content>
|
|
||||||
</Item>
|
|
||||||
)
|
|
||||||
:
|
|
||||||
<p>No Results</p>
|
|
||||||
}
|
|
||||||
</Item.Group>
|
|
||||||
|
|
||||||
{response.results.length > 20 && numShow !== 100 ?
|
|
||||||
<Button
|
|
||||||
content='Load More'
|
|
||||||
onClick={() => {setNumShow(100); numShowCache = 100;}}
|
|
||||||
/> : ''
|
|
||||||
}
|
|
||||||
</>
|
|
||||||
:
|
:
|
||||||
<p>Loading...</p>
|
<p>Participate in this list on the <Link to='/account'>Account Settings</Link> page.</p>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
{response ?
|
||||||
|
<>
|
||||||
|
<Item.Group unstackable divided>
|
||||||
|
{response.results.length ?
|
||||||
|
response.results.slice(0, numShow).map((x, i) =>
|
||||||
|
<Item key={x.member.id} as={Link} to={'/members/'+x.member.id}>
|
||||||
|
<div className='list-num'>{i+1}</div>
|
||||||
|
<Item.Image size='tiny' src={x.member.photo_small ? staticUrl + '/' + x.member.photo_small : '/nophoto.png'} />
|
||||||
|
<Item.Content verticalAlign='top'>
|
||||||
|
<Item.Header>
|
||||||
|
<Icon name='circle' color={statusColor[x.member.status]} />
|
||||||
|
{x.member.preferred_name} {x.member.last_name}
|
||||||
|
</Item.Header>
|
||||||
|
<Item.Description>Status: {x.member.status || 'Unknown'}</Item.Description>
|
||||||
|
<Item.Description>Joined: {x.member.application_date || 'Unknown'}</Item.Description>
|
||||||
|
<Item.Description>ID: {x.member.id}</Item.Description>
|
||||||
|
</Item.Content>
|
||||||
|
</Item>
|
||||||
|
)
|
||||||
|
:
|
||||||
|
<p>No Results</p>
|
||||||
|
}
|
||||||
|
</Item.Group>
|
||||||
|
|
||||||
|
{response.results.length > 20 && numShow !== 100 ?
|
||||||
|
<Button
|
||||||
|
content='Load More'
|
||||||
|
onClick={() => {setNumShow(100); numShowCache = 100;}}
|
||||||
|
/> : ''
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
:
|
||||||
|
<p>Loading...</p>
|
||||||
}
|
}
|
||||||
|
|
||||||
</Container>
|
</Container>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user