Make the Class list publicly available, add Class Feed page
This commit is contained in:
parent
e6aaef9bf1
commit
987e2a7465
|
@ -230,7 +230,7 @@ class CardViewSet(Base, Create, Retrieve, Update, Destroy):
|
||||||
|
|
||||||
|
|
||||||
class CourseViewSet(Base, List, Retrieve, Create, Update):
|
class CourseViewSet(Base, List, Retrieve, Create, Update):
|
||||||
permission_classes = [AllowMetadata | IsAuthenticated, IsAdminOrReadOnly | IsInstructorOrReadOnly]
|
permission_classes = [AllowMetadata | IsAuthenticatedOrReadOnly, IsAdminOrReadOnly | IsInstructorOrReadOnly]
|
||||||
queryset = models.Course.objects.annotate(date=Max('sessions__datetime')).order_by('-date')
|
queryset = models.Course.objects.annotate(date=Max('sessions__datetime')).order_by('-date')
|
||||||
|
|
||||||
def get_serializer_class(self):
|
def get_serializer_class(self):
|
||||||
|
@ -241,7 +241,7 @@ class CourseViewSet(Base, List, Retrieve, Create, Update):
|
||||||
|
|
||||||
|
|
||||||
class SessionViewSet(Base, List, Retrieve, Create, Update):
|
class SessionViewSet(Base, List, Retrieve, Create, Update):
|
||||||
permission_classes = [AllowMetadata | IsAuthenticated, IsAdminOrReadOnly | IsInstructorOrReadOnly]
|
permission_classes = [AllowMetadata | IsAuthenticatedOrReadOnly, IsAdminOrReadOnly | IsInstructorOrReadOnly]
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
if self.action == 'list':
|
if self.action == 'list':
|
||||||
|
|
|
@ -18,7 +18,7 @@ import { Admin } from './Admin.js';
|
||||||
import { Paste } from './Paste.js';
|
import { Paste } from './Paste.js';
|
||||||
import { Sign } from './Sign.js';
|
import { Sign } from './Sign.js';
|
||||||
import { Courses, CourseDetail } from './Courses.js';
|
import { Courses, CourseDetail } from './Courses.js';
|
||||||
import { Classes, ClassDetail } from './Classes.js';
|
import { ClassFeed, Classes, ClassDetail } from './Classes.js';
|
||||||
import { Members, MemberDetail } from './Members.js';
|
import { Members, MemberDetail } from './Members.js';
|
||||||
import { Charts } from './Charts.js';
|
import { Charts } from './Charts.js';
|
||||||
import { Auth } from './Auth.js';
|
import { Auth } from './Auth.js';
|
||||||
|
@ -112,206 +112,216 @@ function App() {
|
||||||
<div className='content-wrap'>
|
<div className='content-wrap'>
|
||||||
<div className='content-wrap-inside'>
|
<div className='content-wrap-inside'>
|
||||||
|
|
||||||
<Container>
|
<Switch>
|
||||||
<div className='hero'>
|
<Route exact path='/classfeed'>
|
||||||
<Link to='/'>
|
<ClassFeed />
|
||||||
<img src='/logo-long.svg' className='logo-long' />
|
</Route>
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{window.location.hostname !== 'my.protospace.ca' &&
|
<Route path='/'>
|
||||||
<p style={{ background: 'yellow' }}>~~~~~ Development site ~~~~~</p>
|
<Container>
|
||||||
}
|
<div className='hero'>
|
||||||
</Container>
|
<Link to='/'>
|
||||||
|
<img src='/logo-long.svg' className='logo-long' />
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Menu>
|
{window.location.hostname !== 'my.protospace.ca' &&
|
||||||
<Container>
|
<p style={{ background: 'yellow' }}>~~~~~ Development site ~~~~~</p>
|
||||||
<Menu.Item
|
}
|
||||||
content='Home'
|
</Container>
|
||||||
as={Link}
|
|
||||||
to='/'
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Dropdown item text='Member' id='ps-menu'>
|
<Menu>
|
||||||
<Dropdown.Menu>
|
<Container>
|
||||||
<Dropdown.Item
|
<Menu.Item
|
||||||
content='Account'
|
content='Home'
|
||||||
as={Link}
|
as={Link}
|
||||||
to='/account'
|
to='/'
|
||||||
/>
|
|
||||||
<Dropdown.Item
|
|
||||||
content='Transactions'
|
|
||||||
as={Link}
|
|
||||||
to='/transactions'
|
|
||||||
/>
|
|
||||||
<Dropdown.Item
|
|
||||||
content='Paymaster'
|
|
||||||
as={Link}
|
|
||||||
to='/paymaster'
|
|
||||||
/>
|
|
||||||
<Dropdown.Item
|
|
||||||
content='Training'
|
|
||||||
as={Link}
|
|
||||||
to='/training'
|
|
||||||
/>
|
|
||||||
<Dropdown.Item
|
|
||||||
content='Cards / Access'
|
|
||||||
as={Link}
|
|
||||||
to='/cards'
|
|
||||||
/>
|
|
||||||
</Dropdown.Menu>
|
|
||||||
</Dropdown>
|
|
||||||
|
|
||||||
<Dropdown item text='Space' id='ps-menu'>
|
|
||||||
<Dropdown.Menu>
|
|
||||||
<Dropdown.Item
|
|
||||||
content='Member List'
|
|
||||||
as={Link}
|
|
||||||
to='/members'
|
|
||||||
/>
|
|
||||||
<Dropdown.Item
|
|
||||||
content='Classes'
|
|
||||||
as={Link}
|
|
||||||
to='/classes'
|
|
||||||
/>
|
|
||||||
<Dropdown.Item
|
|
||||||
content='Utilities'
|
|
||||||
as={Link}
|
|
||||||
to='/utils'
|
|
||||||
/>
|
|
||||||
<Dropdown.Item
|
|
||||||
content='Charts'
|
|
||||||
as={Link}
|
|
||||||
to='/charts'
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{user && isAdmin(user) && <Dropdown.Item
|
<Dropdown item text='Member' id='ps-menu'>
|
||||||
content='Admin'
|
<Dropdown.Menu>
|
||||||
as={Link}
|
<Dropdown.Item
|
||||||
to='/admin'
|
content='Account'
|
||||||
/>}
|
as={Link}
|
||||||
|
to='/account'
|
||||||
|
/>
|
||||||
|
<Dropdown.Item
|
||||||
|
content='Transactions'
|
||||||
|
as={Link}
|
||||||
|
to='/transactions'
|
||||||
|
/>
|
||||||
|
<Dropdown.Item
|
||||||
|
content='Paymaster'
|
||||||
|
as={Link}
|
||||||
|
to='/paymaster'
|
||||||
|
/>
|
||||||
|
<Dropdown.Item
|
||||||
|
content='Training'
|
||||||
|
as={Link}
|
||||||
|
to='/training'
|
||||||
|
/>
|
||||||
|
<Dropdown.Item
|
||||||
|
content='Cards / Access'
|
||||||
|
as={Link}
|
||||||
|
to='/cards'
|
||||||
|
/>
|
||||||
|
</Dropdown.Menu>
|
||||||
|
</Dropdown>
|
||||||
|
|
||||||
{user && isAdmin(user) && <Dropdown.Item
|
<Dropdown item text='Space' id='ps-menu'>
|
||||||
content='Transactions'
|
<Dropdown.Menu>
|
||||||
as={Link}
|
<Dropdown.Item
|
||||||
to='/admintrans'
|
content='Member List'
|
||||||
/>}
|
as={Link}
|
||||||
</Dropdown.Menu>
|
to='/members'
|
||||||
</Dropdown>
|
/>
|
||||||
|
<Dropdown.Item
|
||||||
|
content='Classes'
|
||||||
|
as={Link}
|
||||||
|
to='/classes'
|
||||||
|
/>
|
||||||
|
<Dropdown.Item
|
||||||
|
content='Utilities'
|
||||||
|
as={Link}
|
||||||
|
to='/utils'
|
||||||
|
/>
|
||||||
|
<Dropdown.Item
|
||||||
|
content='Charts'
|
||||||
|
as={Link}
|
||||||
|
to='/charts'
|
||||||
|
/>
|
||||||
|
|
||||||
{user && <Menu.Menu position='right'>
|
{user && isAdmin(user) && <Dropdown.Item
|
||||||
<Menu.Item
|
content='Admin'
|
||||||
content={yousure ? 'You Sure?' : 'Log Out'}
|
as={Link}
|
||||||
onClick={logout}
|
to='/admin'
|
||||||
icon='cancel'
|
/>}
|
||||||
/>
|
|
||||||
<Menu.Item fitted content='' />
|
|
||||||
</Menu.Menu>}
|
|
||||||
</Container>
|
|
||||||
</Menu>
|
|
||||||
|
|
||||||
<Route exact path='/'>
|
{user && isAdmin(user) && <Dropdown.Item
|
||||||
<Home token={token} setTokenCache={setTokenCache} user={user} refreshUser={refreshUser} />
|
content='Transactions'
|
||||||
</Route>
|
as={Link}
|
||||||
|
to='/admintrans'
|
||||||
|
/>}
|
||||||
|
</Dropdown.Menu>
|
||||||
|
</Dropdown>
|
||||||
|
|
||||||
<div className='topPadding'>
|
{user && <Menu.Menu position='right'>
|
||||||
<Switch>
|
<Menu.Item
|
||||||
<Route path='/password/reset/confirm/:uid/:token'>
|
content={yousure ? 'You Sure?' : 'Log Out'}
|
||||||
<ConfirmReset />
|
onClick={logout}
|
||||||
</Route>
|
icon='cancel'
|
||||||
<Route path='/password/reset'>
|
/>
|
||||||
<PasswordReset />
|
<Menu.Item fitted content='' />
|
||||||
|
</Menu.Menu>}
|
||||||
|
</Container>
|
||||||
|
</Menu>
|
||||||
|
|
||||||
|
<Route exact path='/'>
|
||||||
|
<Home token={token} setTokenCache={setTokenCache} user={user} refreshUser={refreshUser} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
<Route path='/utils'>
|
<div className='topPadding'>
|
||||||
<Paste token={token} />
|
|
||||||
</Route>
|
|
||||||
|
|
||||||
<Route path='/sign'>
|
|
||||||
<Sign token={token} />
|
|
||||||
</Route>
|
|
||||||
|
|
||||||
<Route path='/charts'>
|
|
||||||
<Charts />
|
|
||||||
</Route>
|
|
||||||
|
|
||||||
<Route path='/auth'>
|
|
||||||
<Auth user={user} />
|
|
||||||
</Route>
|
|
||||||
|
|
||||||
<Route path='/subscribe'>
|
|
||||||
<Subscribe />
|
|
||||||
</Route>
|
|
||||||
|
|
||||||
{user && user.member.set_details ?
|
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path='/account'>
|
<Route path='/password/reset/confirm/:uid/:token'>
|
||||||
<Account token={token} user={user} refreshUser={refreshUser} />
|
<ConfirmReset />
|
||||||
|
</Route>
|
||||||
|
<Route path='/password/reset'>
|
||||||
|
<PasswordReset />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
<Route path='/transactions/:id'>
|
<Route path='/utils'>
|
||||||
<TransactionDetail token={token} user={user} refreshUser={refreshUser} />
|
<Paste token={token} />
|
||||||
</Route>
|
|
||||||
<Route path='/transactions'>
|
|
||||||
<Transactions user={user} />
|
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
<Route path='/paymaster'>
|
<Route path='/sign'>
|
||||||
<Paymaster user={user} />
|
<Sign token={token} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
<Route path='/cards'>
|
<Route path='/charts'>
|
||||||
<Cards token={token} user={user} />
|
<Charts />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
<Route path='/training'>
|
<Route path='/auth'>
|
||||||
<Training user={user} />
|
<Auth user={user} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
<Route path='/courses/:id'>
|
<Route path='/subscribe'>
|
||||||
<CourseDetail token={token} user={user} />
|
<Subscribe />
|
||||||
</Route>
|
|
||||||
<Route path='/courses'>
|
|
||||||
<Courses token={token} user={user} />
|
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
<Route path='/classes/:id'>
|
<Route exact path='/classes'>
|
||||||
<ClassDetail token={token} user={user} refreshUser={refreshUser} />
|
|
||||||
</Route>
|
|
||||||
<Route path='/classes'>
|
|
||||||
<Classes token={token} />
|
<Classes token={token} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
<Route path='/members/:id'>
|
{user && user.member.set_details ?
|
||||||
<MemberDetail token={token} user={user} />
|
<Switch>
|
||||||
</Route>
|
<Route path='/account'>
|
||||||
<Route path='/members'>
|
<Account token={token} user={user} refreshUser={refreshUser} />
|
||||||
<Members token={token} user={user} />
|
</Route>
|
||||||
</Route>
|
|
||||||
|
|
||||||
{user && isAdmin(user) &&
|
<Route path='/transactions/:id'>
|
||||||
<Route path='/admin'>
|
<TransactionDetail token={token} user={user} refreshUser={refreshUser} />
|
||||||
<Admin token={token} user={user} />
|
</Route>
|
||||||
|
<Route path='/transactions'>
|
||||||
|
<Transactions user={user} />
|
||||||
|
</Route>
|
||||||
|
|
||||||
|
<Route path='/paymaster'>
|
||||||
|
<Paymaster user={user} />
|
||||||
|
</Route>
|
||||||
|
|
||||||
|
<Route path='/cards'>
|
||||||
|
<Cards token={token} user={user} />
|
||||||
|
</Route>
|
||||||
|
|
||||||
|
<Route path='/training'>
|
||||||
|
<Training user={user} />
|
||||||
|
</Route>
|
||||||
|
|
||||||
|
<Route path='/courses/:id'>
|
||||||
|
<CourseDetail token={token} user={user} />
|
||||||
|
</Route>
|
||||||
|
|
||||||
|
<Route path='/courses'>
|
||||||
|
<Courses token={token} user={user} />
|
||||||
|
</Route>
|
||||||
|
|
||||||
|
<Route path='/classes/:id'>
|
||||||
|
<ClassDetail token={token} user={user} refreshUser={refreshUser} />
|
||||||
|
</Route>
|
||||||
|
|
||||||
|
<Route path='/members/:id'>
|
||||||
|
<MemberDetail token={token} user={user} />
|
||||||
|
</Route>
|
||||||
|
<Route path='/members'>
|
||||||
|
<Members token={token} user={user} />
|
||||||
|
</Route>
|
||||||
|
|
||||||
|
{user && isAdmin(user) &&
|
||||||
|
<Route path='/admin'>
|
||||||
|
<Admin token={token} user={user} />
|
||||||
|
</Route>
|
||||||
|
}
|
||||||
|
|
||||||
|
{user && isAdmin(user) &&
|
||||||
|
<Route path='/admintrans'>
|
||||||
|
<AdminTransactions token={token} user={user} />
|
||||||
|
</Route>
|
||||||
|
}
|
||||||
|
|
||||||
|
<Route path='/:page'>
|
||||||
|
<NotFound />
|
||||||
|
</Route>
|
||||||
|
</Switch>
|
||||||
|
:
|
||||||
|
<Route path='/:page'>
|
||||||
|
<PleaseLogin />
|
||||||
</Route>
|
</Route>
|
||||||
}
|
}
|
||||||
|
|
||||||
{user && isAdmin(user) &&
|
|
||||||
<Route path='/admintrans'>
|
|
||||||
<AdminTransactions token={token} user={user} />
|
|
||||||
</Route>
|
|
||||||
}
|
|
||||||
|
|
||||||
<Route path='/:page'>
|
|
||||||
<NotFound />
|
|
||||||
</Route>
|
|
||||||
</Switch>
|
</Switch>
|
||||||
:
|
</div>
|
||||||
<Route path='/:page'>
|
</Route>
|
||||||
<PleaseLogin />
|
</Switch>
|
||||||
</Route>
|
|
||||||
}
|
|
||||||
</Switch>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -50,6 +50,43 @@ function ClassTable(props) {
|
||||||
|
|
||||||
let classesCache = false;
|
let classesCache = false;
|
||||||
|
|
||||||
|
export function ClassFeed(props) {
|
||||||
|
const [classes, setClasses] = useState(classesCache);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const get = async() => {
|
||||||
|
requester('/sessions/', 'GET', '')
|
||||||
|
.then(res => {
|
||||||
|
setClasses(res.results);
|
||||||
|
classesCache = res.results;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
get();
|
||||||
|
const interval = setInterval(get, 60000);
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const now = new Date().toISOString();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container>
|
||||||
|
<p/>
|
||||||
|
|
||||||
|
<Header size='large'>Upcoming Protospace Classes</Header>
|
||||||
|
|
||||||
|
{classes ?
|
||||||
|
<ClassTable classes={classes.filter(x => x.datetime > now).sort((a, b) => a.datetime > b.datetime ? 1 : -1)} />
|
||||||
|
:
|
||||||
|
<p>Loading...</p>
|
||||||
|
}
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export function Classes(props) {
|
export function Classes(props) {
|
||||||
const [classes, setClasses] = useState(classesCache);
|
const [classes, setClasses] = useState(classesCache);
|
||||||
const { token } = props;
|
const { token } = props;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user