From 6091d255d22174041928c7901af9b7551b899648 Mon Sep 17 00:00:00 2001 From: Tanner Collin Date: Sat, 3 Jun 2023 19:43:14 +0000 Subject: [PATCH] Improve tables on mobile --- webclient/src/Admin.js | 38 ++++++++++++++++-------------- webclient/src/AdminTransactions.js | 13 +++++----- webclient/src/Cards.js | 13 +++++----- webclient/src/Courses.js | 24 ++++++++++--------- webclient/src/Training.js | 34 +++++++++++++------------- webclient/src/Transactions.js | 13 +++++----- 6 files changed, 72 insertions(+), 63 deletions(-) diff --git a/webclient/src/Admin.js b/webclient/src/Admin.js index c6841a9..6e49096 100644 --- a/webclient/src/Admin.js +++ b/webclient/src/Admin.js @@ -5,7 +5,7 @@ import { Button, Container, Checkbox, Form, Header, Icon, Table } from 'semantic import * as Datetime from 'react-datetime'; import moment from 'moment-timezone'; import download from 'downloadjs'; -import { apiUrl, statusColor, requester } from './utils.js'; +import { apiUrl, statusColor, requester, useIsMobile } from './utils.js'; let vettingCache = false; let historyCache = false; @@ -123,6 +123,7 @@ export function AdminHistory(props) { const [excludeSystem, setExcludeSystem] = useState(excludeSystemCache); const [focus, setFocus] = useState(focusCache); const [error, setError] = useState(false); + const isMobile = useIsMobile(); const handleExcludeSystem = (e, v) => { setExcludeSystem(v.checked); @@ -154,7 +155,7 @@ export function AdminHistory(props) { /> - + {!isMobile && Date Username @@ -163,7 +164,7 @@ export function AdminHistory(props) { Object Changed Fields - + } {history.map(x => @@ -174,11 +175,11 @@ export function AdminHistory(props) { {moment.utc(x.history_date).tz('America/Edmonton').format('YYYY-MM-DD')} - {x.is_system ? 'System' : (x.history_user || 'Deleted User')} - {x.history_type} - {x.owner_name} - {x.object_name} - {x.changes.map(x => x.field).join(', ')} + {isMobile && 'User: '}{x.is_system ? 'System' : (x.history_user || 'Deleted User')} + {isMobile && 'Type: '}{x.history_type} + {isMobile && 'Owner: '}{x.owner_name} + {isMobile && 'Object: '}{x.object_name} + {isMobile && 'Changed: '}{x.changes.map(x => x.field).join(', ')} {focus === x.id && @@ -186,19 +187,19 @@ export function AdminHistory(props) {

Object ID: {x.object_id}, Database Revert

{!!x.changes.length &&
- + {!isMobile && Change Before After - + } {x.changes.map(y => - {y.field} - {y.old} - {y.new} + {isMobile && 'Change: '}{y.field} + {isMobile && 'Before: '}{y.old} + {isMobile && 'After: '}{y.new} )} @@ -225,6 +226,7 @@ let backupsCache = false; export function AdminBackups(props) { const [backups, setBackups] = useState(backupsCache); const [error, setError] = useState(false); + const isMobile = useIsMobile(); useEffect(() => { requester('/backup/', 'GET') @@ -243,20 +245,20 @@ export function AdminBackups(props) { {!error ? backups ?
- + {!isMobile && Username Last Downloaded Less than 24 hours ago? - + } {backups.filter(x => x.download_time).map(x => - {x.backup_user} - {moment.utc(x.download_time).tz('America/Edmonton').format('LLLL')} - {x.less_than_24h ? 'Yes' : 'No - please investigate'} + {isMobile && 'User: '}{x.backup_user} + {isMobile && 'Last: '}{moment.utc(x.download_time).tz('America/Edmonton').format('LLLL')} + {isMobile && '24h ago: '}{x.less_than_24h ? 'Yes' : 'No - please investigate'} )} diff --git a/webclient/src/AdminTransactions.js b/webclient/src/AdminTransactions.js index c19c5b8..8ae068e 100644 --- a/webclient/src/AdminTransactions.js +++ b/webclient/src/AdminTransactions.js @@ -5,7 +5,7 @@ import { Container, Checkbox, Form, Header, Segment, Table } from 'semantic-ui-r import * as Datetime from 'react-datetime'; import 'react-datetime/css/react-datetime.css'; import moment from 'moment'; -import { requester } from './utils.js'; +import { requester, useIsMobile } from './utils.js'; import { TransactionList, TransactionEditor } from './Transactions.js'; export function AdminReportedTransactions(props) { @@ -53,6 +53,7 @@ export function AdminHistoricalTransactions(props) { const [excludeSnacks, setExcludeSnacks] = useState(true); const [loading, setLoading] = useState(false); const [error, setError] = useState(false); + const isMobile = useIsMobile(); const handleDatetime = (v) => setInput({ ...input, month: v }); @@ -129,20 +130,20 @@ export function AdminHistoricalTransactions(props) {
Summary
- + {!isMobile && Category Dollar Protocoin - + } {summary.map(x => - {x.category} - {'$ ' + x.dollar.toFixed(2)} - {'₱ ' + x.protocoin.toFixed(2)} + {isMobile && 'Category: '}{x.category} + {isMobile && 'Dollar: '}{'$ ' + x.dollar.toFixed(2)} + {isMobile && 'Protocoin: '}{'₱ ' + x.protocoin.toFixed(2)} )} diff --git a/webclient/src/Cards.js b/webclient/src/Cards.js index 89a77d7..8c0a58f 100644 --- a/webclient/src/Cards.js +++ b/webclient/src/Cards.js @@ -2,11 +2,12 @@ import React, { useState } from 'react'; import './light.css'; import moment from 'moment-timezone'; import { Button, Container, Header, Table } from 'semantic-ui-react'; -import { BasicTable, staticUrl } from './utils.js'; +import { BasicTable, staticUrl, useIsMobile } from './utils.js'; export function Cards(props) { const { user, token } = props; const [open, setOpen] = useState(false); + const isMobile = useIsMobile(); const cardStatus = (c) => c.active_status === 'card_active' ? 'Yes' : 'No'; const card = user.cards[0]; @@ -30,22 +31,22 @@ export function Cards(props) { {user.cards.length ? user.cards.length > 1 ?
- + {!isMobile && Number Notes Last Scan Active - + } {user.cards.map(x => {x.card_number} - {x.notes} + {isMobile && 'Notes: '}{x.notes} - {x.last_seen ? + {isMobile && 'Last Scan: '}{x.last_seen ? x.last_seen > '2021-11-14T02:01:35.415685Z' ? moment.utc(x.last_seen).tz('America/Edmonton').format('lll') : @@ -54,7 +55,7 @@ export function Cards(props) { 'Unknown' } - {cardStatus(x)} + {isMobile && 'Active: '}{cardStatus(x)} )} diff --git a/webclient/src/Courses.js b/webclient/src/Courses.js index c696875..8929d3f 100644 --- a/webclient/src/Courses.js +++ b/webclient/src/Courses.js @@ -3,7 +3,7 @@ import { Link, useParams } from 'react-router-dom'; import './light.css'; import { Button, Label, Container, Header, Segment, Table } from 'semantic-ui-react'; import moment from 'moment-timezone'; -import { isInstructor, getInstructor, requester } from './utils.js'; +import { isInstructor, getInstructor, requester, useIsMobile } from './utils.js'; import { NotFound } from './Misc.js'; import { InstructorCourseList, InstructorCourseDetail } from './InstructorCourses.js'; import { InstructorClassList } from './InstructorClasses.js'; @@ -31,6 +31,7 @@ export function Courses(props) { const [courses, setCourses] = useState(courseCache); const [tagFilter, setTagFilter] = useState(tagFilterCache); const { token, user } = props; + const isMobile = useIsMobile(); useEffect(() => { requester('/courses/', 'GET', token) @@ -95,13 +96,13 @@ export function Courses(props) { {courses ?
- + {!isMobile && Name Interest - + } {courses.length ? @@ -111,7 +112,7 @@ export function Courses(props) { {x.name} - {!!x.num_interested && + {isMobile && 'Interest: '}{!!x.num_interested && <>{x.num_interested} member{x.num_interested !== 1 && 's'} } @@ -143,6 +144,7 @@ export function CourseDetail(props) { const [loading, setLoading] = useState(false); const { token, user, refreshUser } = props; const { id } = useParams(); + const isMobile = useIsMobile(); const handleInterest = () => { if (loading) return; @@ -223,7 +225,7 @@ export function CourseDetail(props) { }
- + {!isMobile && Date Time @@ -231,7 +233,7 @@ export function CourseDetail(props) { Cost Students - + } {course.sessions.length ? @@ -239,14 +241,14 @@ export function CourseDetail(props) { -  {moment.utc(x.datetime).tz('America/Edmonton').format('ll')} + {!isMobile &&  }{moment.utc(x.datetime).tz('America/Edmonton').format('ll')} - {x.is_cancelled ? 'Cancelled' : moment.utc(x.datetime).tz('America/Edmonton').format('LT')} - {getInstructor(x)} - {x.cost === '0.00' ? 'Free' : '$'+x.cost} + {isMobile && 'Time: '}{x.is_cancelled ? 'Cancelled' : moment.utc(x.datetime).tz('America/Edmonton').format('LT')} + {isMobile && 'Instructor: '}{getInstructor(x)} + {isMobile && 'Cost: '}{x.cost === '0.00' ? 'Free' : '$'+x.cost} - {!!x.max_students ? + {isMobile && 'Students: '}{!!x.max_students ? x.max_students <= x.student_count ? 'Full' : diff --git a/webclient/src/Training.js b/webclient/src/Training.js index 5395cef..05d8384 100644 --- a/webclient/src/Training.js +++ b/webclient/src/Training.js @@ -3,10 +3,11 @@ import { Link } from 'react-router-dom'; import './light.css'; import { Container, Header, Popup, Table } from 'semantic-ui-react'; import moment from 'moment-timezone'; -import { getInstructor } from './utils.js'; +import { getInstructor, useIsMobile } from './utils.js'; export function CertList(props) { const { member } = props; + const isMobile = useIsMobile(); const MoreCert = (tools) => ( @@ -17,58 +18,58 @@ export function CertList(props) { return (
- + {!isMobile && Name Certification Course - + } Common {MoreCert('Anything larger than a screwdriver.')} - {member.vetted_date || member.orientation_date ? 'Yes' : 'No'} + {isMobile && 'Certified: '}{member.vetted_date || member.orientation_date ? 'Yes' : 'No'} New Members: Orientation and Basic Safety Wood 1 {MoreCert('Table saw, band saw, chop saw, router.')} - {member.wood_cert_date ? 'Yes, ' + member.wood_cert_date : 'No'} + {isMobile && 'Certified: '}{member.wood_cert_date ? 'Yes, ' + member.wood_cert_date : 'No'} Woodworking Tools 1: Intro to Saws Wood 2 {MoreCert('Jointer, thickness planer, drum sander.')} - {member.wood2_cert_date ? 'Yes, ' + member.wood2_cert_date : 'No'} + {isMobile && 'Certified: '}{member.wood2_cert_date ? 'Yes, ' + member.wood2_cert_date : 'No'} Woodworking Tools 2: Jointer, Thickness Planer, Drum Sander Lathe {MoreCert('Manual metal lathe.')} - {member.lathe_cert_date ? 'Yes, ' + member.lathe_cert_date : 'No'} + {isMobile && 'Certified: '}{member.lathe_cert_date ? 'Yes, ' + member.lathe_cert_date : 'No'} Metal: Metal Cutting & Manual Lathe Mill {MoreCert('Manual metal mill.')} - {member.mill_cert_date ? 'Yes, ' + member.mill_cert_date : 'No'} + {isMobile && 'Certified: '}{member.mill_cert_date ? 'Yes, ' + member.mill_cert_date : 'No'} Metal: Manual Mill & Advanced Lathe Tormach CNC - {member.tormach_cnc_cert_date ? 'Yes, ' + member.tormach_cnc_cert_date : 'No'} + {isMobile && 'Certified: '}{member.tormach_cnc_cert_date ? 'Yes, ' + member.tormach_cnc_cert_date : 'No'} Tormach: CAM and Tormach Intro Precix CNC - {member.precix_cnc_cert_date ? 'Yes, ' + member.precix_cnc_cert_date : 'No'} + {isMobile && 'Certified: '}{member.precix_cnc_cert_date ? 'Yes, ' + member.precix_cnc_cert_date : 'No'} Basic CNC Wood Router Rabbit Laser - {member.rabbit_cert_date ? 'Yes, ' + member.rabbit_cert_date : 'No'} + {isMobile && 'Certified: '}{member.rabbit_cert_date ? 'Yes, ' + member.rabbit_cert_date : 'No'} Laser: Cutting and Engraving Trotec Laser - {member.trotec_cert_date ? 'Yes, ' + member.trotec_cert_date : 'No'} + {isMobile && 'Certified: '}{member.trotec_cert_date ? 'Yes, ' + member.trotec_cert_date : 'No'} Laser: Trotec Course @@ -78,17 +79,18 @@ export function CertList(props) { export function TrainingList(props) { const { training } = props; + const isMobile = useIsMobile(); return (
- + {!isMobile && Course / Event Name Class Date Status Instructor - + } {training.slice().sort((a, b) => a.session.datetime < b.session.datetime ? 1 : -1).map(x => @@ -97,8 +99,8 @@ export function TrainingList(props) { {moment(x.session.datetime).tz('America/Edmonton').format('ll')} - {x.attendance_status} - {getInstructor(x.session)} + {isMobile && 'Attendance: '}{x.attendance_status} + {isMobile && 'Instructor: '}{getInstructor(x.session)} )} diff --git a/webclient/src/Transactions.js b/webclient/src/Transactions.js index be03b14..bd06e14 100644 --- a/webclient/src/Transactions.js +++ b/webclient/src/Transactions.js @@ -5,7 +5,7 @@ import ReactToPrint from 'react-to-print'; import './light.css'; import { Button, Container, Form, Grid, Header, Message, Segment, Table } from 'semantic-ui-react'; import { MembersDropdown } from './Members.js'; -import { isAdmin, BasicTable, requester } from './utils.js'; +import { isAdmin, BasicTable, requester, useIsMobile } from './utils.js'; import { NotFound } from './Misc.js'; export function TransactionEditor(props) { @@ -214,10 +214,11 @@ function EditTransaction(props) { export function TransactionList(props) { const { transactions, noMember, noCategory } = props; + const isMobile = useIsMobile(); return (
- + {!isMobile && Date {!noMember && Member} @@ -226,7 +227,7 @@ export function TransactionList(props) { {!noCategory && Category} Memo - + } {transactions.length ? @@ -244,9 +245,9 @@ export function TransactionList(props) { x.member_name } } - {x.protocoin !== '0.00' ? '₱ ' + x.protocoin : '$ ' + x.amount} - {x.account_type} - {!noCategory && {x.category}} + {isMobile && 'Amount: '}{x.protocoin !== '0.00' ? '₱ ' + x.protocoin : '$ ' + x.amount} + {isMobile && 'Method: '}{x.account_type} + {!noCategory && {isMobile && 'Category: '}{x.category}} {x.memo || x.report_memo} )