Add table of all storage locations
This commit is contained in:
		@@ -27,7 +27,7 @@ import { Subscribe } from './PayPal.js';
 | 
			
		||||
import { PasswordReset, ConfirmReset } from './PasswordReset.js';
 | 
			
		||||
import { NotFound, PleaseLogin } from './Misc.js';
 | 
			
		||||
import { Debug } from './Debug.js';
 | 
			
		||||
import { StorageDetail, ClaimShelf } from './Storage.js';
 | 
			
		||||
import { Storage, StorageDetail, ClaimShelf } from './Storage.js';
 | 
			
		||||
import { Garden } from './Garden.js';
 | 
			
		||||
import { Footer } from './Footer.js';
 | 
			
		||||
import { LCARS1Display, LCARS2Display } from './Display.js';
 | 
			
		||||
@@ -244,6 +244,10 @@ function App() {
 | 
			
		||||
								<StorageDetail token={token} user={user} />
 | 
			
		||||
							</Route>
 | 
			
		||||
 | 
			
		||||
							<Route path='/storage'>
 | 
			
		||||
								<Storage token={token} user={user} />
 | 
			
		||||
							</Route>
 | 
			
		||||
 | 
			
		||||
							<Route path='/debug'>
 | 
			
		||||
								<Debug token={token} user={user} />
 | 
			
		||||
							</Route>
 | 
			
		||||
 
 | 
			
		||||
@@ -345,7 +345,7 @@ export function Classes(props) {
 | 
			
		||||
		<Container>
 | 
			
		||||
			<Header size='large'>Class List</Header>
 | 
			
		||||
 | 
			
		||||
			<p><Link to={'/courses'}>Click here to view the list of all courses.</Link></p>
 | 
			
		||||
			<p><Link to={'/courses'}>View the list of all courses.</Link></p>
 | 
			
		||||
 | 
			
		||||
			{!!user && !!classes.length && !!classes.filter(byTeaching).length &&
 | 
			
		||||
				<>
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ import { statusColor, BasicTable, siteUrl, staticUrl, requester, isAdmin } from
 | 
			
		||||
import { LoginForm, SignupForm } from './LoginSignup.js';
 | 
			
		||||
import { AccountForm } from './Account.js';
 | 
			
		||||
import { SignForm } from './Sign.js';
 | 
			
		||||
import { StorageButton } from './Storage.js';
 | 
			
		||||
import { PayPalSubscribeDeal } from './PayPal.js';
 | 
			
		||||
 | 
			
		||||
function MemberInfo(props) {
 | 
			
		||||
@@ -21,11 +22,6 @@ function MemberInfo(props) {
 | 
			
		||||
 | 
			
		||||
	const unpaidTraining = user.training?.filter(x => x.attendance_status === 'Waiting for payment');
 | 
			
		||||
 | 
			
		||||
	const handleStorageButton = (e, id) => {
 | 
			
		||||
		e.preventDefault();
 | 
			
		||||
		history.push('/storage/' + id);
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	return (
 | 
			
		||||
		<div>
 | 
			
		||||
			{member.protocoin < 0 && <Message error>
 | 
			
		||||
@@ -67,14 +63,8 @@ function MemberInfo(props) {
 | 
			
		||||
								<Table.Cell>Shelf:</Table.Cell>
 | 
			
		||||
								<Table.Cell>
 | 
			
		||||
									{user.storage.length ?
 | 
			
		||||
										user.storage.map((x, i) =>
 | 
			
		||||
											<Button
 | 
			
		||||
												className='storage-button'
 | 
			
		||||
												onClick={(e) => handleStorageButton(e, x.id)}
 | 
			
		||||
												size='tiny'
 | 
			
		||||
											>
 | 
			
		||||
												{x.shelf_id}
 | 
			
		||||
											</Button>
 | 
			
		||||
										user.storage.sort((a, b) => a.location == 'member_shelves' ? -1 : 1).map((x, i) =>
 | 
			
		||||
											<StorageButton storage={x} />
 | 
			
		||||
										)
 | 
			
		||||
									:
 | 
			
		||||
										<>None <Link to='/claimshelf'>[claim]</Link></>
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@ import { statusColor, isAdmin, isInstructor, BasicTable, staticUrl, requester }
 | 
			
		||||
import { NotFound } from './Misc.js';
 | 
			
		||||
import { AdminMemberInfo, AdminMemberPause, AdminMemberForm, AdminMemberCards, AdminMemberTraining, AdminMemberCertifications } from './AdminMembers.js';
 | 
			
		||||
import { AdminMemberTransactions } from './AdminTransactions.js';
 | 
			
		||||
import { StorageButton } from './Storage.js';
 | 
			
		||||
import AbortController from 'abort-controller';
 | 
			
		||||
 | 
			
		||||
const memberSorts = {
 | 
			
		||||
@@ -166,11 +167,6 @@ export function Members(props) {
 | 
			
		||||
		doSearch(q);
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	const handleStorageButton = (e, id) => {
 | 
			
		||||
		e.preventDefault();
 | 
			
		||||
		history.push('/storage/' + id);
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	useEffect(() => {
 | 
			
		||||
		if (!responseCache) {
 | 
			
		||||
			doSort('recently_vetted');
 | 
			
		||||
@@ -246,14 +242,8 @@ export function Members(props) {
 | 
			
		||||
											<>
 | 
			
		||||
												<Item.Description>
 | 
			
		||||
													Shelf: {x.member.storage.length ?
 | 
			
		||||
														x.member.storage.map((x, i) =>
 | 
			
		||||
															<Button
 | 
			
		||||
																className='storage-button'
 | 
			
		||||
																onClick={(e) => handleStorageButton(e, x.id)}
 | 
			
		||||
																size='tiny'
 | 
			
		||||
															>
 | 
			
		||||
																{x.shelf_id}
 | 
			
		||||
															</Button>
 | 
			
		||||
														x.member.storage.sort((a, b) => a.location == 'member_shelves' ? -1 : 1).map((x, i) =>
 | 
			
		||||
															<StorageButton storage={x} />
 | 
			
		||||
														)
 | 
			
		||||
													:
 | 
			
		||||
														'None'
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,8 @@ import React, { useState, useEffect } from 'react';
 | 
			
		||||
import { Link, useParams, useHistory } from 'react-router-dom';
 | 
			
		||||
import './light.css';
 | 
			
		||||
import { MembersDropdown } from './Members.js';
 | 
			
		||||
import { isAdmin, BasicTable, requester } from './utils.js';
 | 
			
		||||
import { Button, Container, Form, Grid, Header, Message, Segment, Table } from 'semantic-ui-react';
 | 
			
		||||
import { isAdmin, BasicTable, requester, useIsMobile } from './utils.js';
 | 
			
		||||
import { Button, Container, Form, Grid, Header, Icon, Message, Segment, Table } from 'semantic-ui-react';
 | 
			
		||||
 | 
			
		||||
export function StorageEditor(props) {
 | 
			
		||||
	const { token, input, setInput, error } = props;
 | 
			
		||||
@@ -174,6 +174,8 @@ export function StorageDetail(props) {
 | 
			
		||||
					<div>
 | 
			
		||||
						<Header size='large'>Storage Location</Header>
 | 
			
		||||
 | 
			
		||||
						<p><Link to={'/storage'}>View the list of all storage locations.</Link></p>
 | 
			
		||||
 | 
			
		||||
						<Grid stackable columns={2}>
 | 
			
		||||
							<Grid.Column width={6}>
 | 
			
		||||
								<StorageTable user={user} storage={storage} />
 | 
			
		||||
@@ -206,10 +208,38 @@ export function StorageDetail(props) {
 | 
			
		||||
	);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function StorageButton(props) {
 | 
			
		||||
	const { storage } = props;
 | 
			
		||||
	const history = useHistory();
 | 
			
		||||
 | 
			
		||||
	const buttonColors = {
 | 
			
		||||
		member_shelves: 'grey',
 | 
			
		||||
		lockers: 'blue',
 | 
			
		||||
		large_project_storage: 'brown',
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	const handleStorageButton = (e, id) => {
 | 
			
		||||
		e.preventDefault();
 | 
			
		||||
		history.push('/storage/' + id);
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	return (
 | 
			
		||||
		<Button
 | 
			
		||||
			className='storage-button'
 | 
			
		||||
			onClick={(e) => handleStorageButton(e, storage.id)}
 | 
			
		||||
			size='tiny'
 | 
			
		||||
			color={buttonColors[storage.location]}
 | 
			
		||||
		>
 | 
			
		||||
			{storage.shelf_id}
 | 
			
		||||
		</Button>
 | 
			
		||||
	);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function StorageList(props) {
 | 
			
		||||
	const { token } = props;
 | 
			
		||||
	const [storageList, setStorageList] = useState(false);
 | 
			
		||||
	const [error, setError] = useState(false);
 | 
			
		||||
	const isMobile = useIsMobile();
 | 
			
		||||
 | 
			
		||||
	useEffect(() => {
 | 
			
		||||
		requester('/storage/', 'GET', token)
 | 
			
		||||
@@ -225,13 +255,34 @@ export function StorageList(props) {
 | 
			
		||||
 | 
			
		||||
	return (
 | 
			
		||||
		<div>
 | 
			
		||||
			<p>
 | 
			
		||||
				<Icon name='circle' color='grey' /> Member shelf <br/>
 | 
			
		||||
				<Icon name='circle' color='blue' /> Locker <br/>
 | 
			
		||||
				<Icon name='circle' color='brown' /> Large project storage
 | 
			
		||||
			</p>
 | 
			
		||||
			{!error ?
 | 
			
		||||
				storageList ?
 | 
			
		||||
					storageList.map(x =>
 | 
			
		||||
						<p><Link to={'/storage/'+x.id}>{x.shelf_id}</Link> - {!!x.member_id &&
 | 
			
		||||
							<Link to={'/members/'+x.member_id}>{x.member_name}</Link>
 | 
			
		||||
						}</p>
 | 
			
		||||
					)
 | 
			
		||||
					<Table basic='very'>
 | 
			
		||||
						<Table.Header>
 | 
			
		||||
							<Table.Row>
 | 
			
		||||
								<Table.HeaderCell>Shelf ID</Table.HeaderCell>
 | 
			
		||||
								<Table.HeaderCell>Owner</Table.HeaderCell>
 | 
			
		||||
								<Table.HeaderCell>Memo</Table.HeaderCell>
 | 
			
		||||
							</Table.Row>
 | 
			
		||||
						</Table.Header>
 | 
			
		||||
 | 
			
		||||
						<Table.Body>
 | 
			
		||||
							{storageList.map(x =>
 | 
			
		||||
								<Table.Row key={x.id}>
 | 
			
		||||
									<Table.Cell><StorageButton storage={x} /></Table.Cell>
 | 
			
		||||
									<Table.Cell>
 | 
			
		||||
										{isMobile && 'Owner: '}<Link to={'/members/'+x.member_id}>{x.member_name}</Link>
 | 
			
		||||
									</Table.Cell>
 | 
			
		||||
									<Table.Cell>{isMobile && 'Memo: '}{x.memo}</Table.Cell>
 | 
			
		||||
								</Table.Row>
 | 
			
		||||
							)}
 | 
			
		||||
						</Table.Body>
 | 
			
		||||
					</Table>
 | 
			
		||||
				:
 | 
			
		||||
					<p>Loading...</p>
 | 
			
		||||
			:
 | 
			
		||||
@@ -241,6 +292,18 @@ export function StorageList(props) {
 | 
			
		||||
	);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function Storage(props) {
 | 
			
		||||
	const { token, user } = props;
 | 
			
		||||
 | 
			
		||||
	return (
 | 
			
		||||
		<Container>
 | 
			
		||||
			<Header size='large'>Storage Locations</Header>
 | 
			
		||||
 | 
			
		||||
			<StorageList {...props} />
 | 
			
		||||
		</Container>
 | 
			
		||||
	);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function ClaimShelfForm(props) {
 | 
			
		||||
	const { token, user, refreshUser } = props;
 | 
			
		||||
	const member = user.member;
 | 
			
		||||
@@ -299,7 +362,6 @@ export function ClaimShelfForm(props) {
 | 
			
		||||
 | 
			
		||||
export function ClaimShelf(props) {
 | 
			
		||||
	const { token, user } = props;
 | 
			
		||||
	const [error, setError] = useState(false);
 | 
			
		||||
 | 
			
		||||
	return (
 | 
			
		||||
		<Container>
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,16 @@
 | 
			
		||||
	color: #db282882 !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.darkmode--activated i.blue.circle.icon {
 | 
			
		||||
	mix-blend-mode: difference;
 | 
			
		||||
	color: #2185d0 !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.darkmode--activated i.brown.circle.icon {
 | 
			
		||||
	mix-blend-mode: difference;
 | 
			
		||||
	color: #a5673f !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.darkmode--activated .footer {
 | 
			
		||||
	mix-blend-mode: difference;
 | 
			
		||||
}
 | 
			
		||||
@@ -62,6 +72,21 @@
 | 
			
		||||
	background: #21ba4582 !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.darkmode--activated .ui.grey.button {
 | 
			
		||||
	mix-blend-mode: difference;
 | 
			
		||||
	background: #767676 !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.darkmode--activated .ui.blue.button {
 | 
			
		||||
	mix-blend-mode: difference;
 | 
			
		||||
	background: #2185d0 !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.darkmode--activated .ui.brown.button {
 | 
			
		||||
	mix-blend-mode: difference;
 | 
			
		||||
	background: #a5673f !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.darkmode--activated .ui.tag.label {
 | 
			
		||||
	mix-blend-mode: difference;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user