Skip to content

Commit

Permalink
Merge pull request #55 from hacksu/dev-main
Browse files Browse the repository at this point in the history
Update users page on staff site, mostly
  • Loading branch information
toBeOfUse authored Apr 18, 2024
2 parents 6620b63 + eb74a75 commit 803654f
Show file tree
Hide file tree
Showing 8 changed files with 325 additions and 117 deletions.
14 changes: 14 additions & 0 deletions global-includes/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,9 @@ export class User extends EntityBase {
@VFields.boolean({ allowApiUpdate: [UserRole.Admin, UserRole.Staff] })
checkedIn = false;

@VFields.boolean({ allowApiUpdate: [UserRole.Admin, UserRole.Staff] })
archived = false;

/** Called on backend when OAuth succeeds; finds or creates a User object in
* the database and returns it. A session is then created using the returned
* User object*/
Expand Down Expand Up @@ -391,6 +394,17 @@ export class User extends EntityBase {
);
}

@BackendMethod({ allowed: true })
static async withdrawRegistration() {
const user = remult.user as User;
if (!user) {
throw "Not logged in";
}
user.submittedApplication = false;
user.applicationApproved = false;
await remult.repo(User).save(user);
}

@BackendMethod({allowed: true})
static async uploadResume(base64Resume: string, filename: string) {
const user = remult.user as User;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"multer": "^1.4.5-lts.1",
"nanoid": "^5.0.6",
"next": "^13.2.4",
"next-usequerystate": "^1.7.2",
"nuqs": "^1.17.1",
"octokit": "^2.0.14",
"parse-headers": "^2.0.5",
"passport": "^0.6.0",
Expand Down
4 changes: 4 additions & 0 deletions public-frontend/src/views/Contact.vue
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ export default {
@import "@/styles/global.scss";
@import '@/styles/space.scss';
::placeholder {
color: black;
}
#contact {
@include bg-primary;
text-align: left;
Expand Down
55 changes: 37 additions & 18 deletions public-frontend/src/views/Profile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -218,25 +218,28 @@
</div>
</template>
<template #footer>
<Button icon="pi pi-check" :label="submissionStatus == 'success' ? 'Revise' : 'Save Draft'" iconPos="right" @click="saveUser" />
<Button :disabled="submissionStatus == 'success'" @click="submissionStatus != 'success' && submitForm()"
icon="pi pi-envelope" :label="submissionStatus == 'success' ? 'Application Submitted!' : 'Submit'" iconPos="right"
:style="'margin-left: 0.5em;' + (formComplete ? `color: #333; background-color: white;` : '')" />
<p v-if="saveStatus == 'failed'" style="text-align: left; color: red;">
Could not update application! Make sure all fields are filled out.
</p>
<p v-if="saveStatus == 'saved'" style="text-align: left; color: lightgreen;">
Saved application!
</p>
<p v-if="submissionStatus == 'success'" style="text-align: left">
Thanks for submitting your application to Kent Hack Enough! You
will receive an email when your application is accepted or
rejected.
<div class="action-buttons">
<Button icon="pi pi-check" :label="submissionStatus == 'success' ? 'Revise' : 'Save Draft'" iconPos="right" @click="saveUser" />
<Button :disabled="submissionStatus == 'success'" @click="submissionStatus != 'success' && submitForm()"
icon="pi pi-envelope" :label="submissionStatus == 'success' ? 'Application Submitted!' : 'Submit'" iconPos="right"
:style="(formComplete ? `color: #333; background-color: white;` : '')" />
<Button v-if="submissionStatus == 'success'" label="Withdraw Application" @click="deregister" />
</div>
<p v-if="saveStatus == 'failed'" style="text-align: left; color: red;">
Could not update application! Make sure all fields are filled out.
</p>
<p v-if="saveStatus == 'saved'" style="text-align: left; color: lightgreen;">
Saved application!
</p>
<p v-if="submissionStatus == 'success'" style="text-align: left">
Thanks for submitting your application to Kent Hack Enough! You
will receive an email when your application is accepted or
rejected.

You are free to make changes to your application and save them,
but please note that this will put your application back at the
end of the line.
</p>
You are free to make changes to your application and save them,
but please note that this will put your application back at the
end of the line.
</p>
</template>
</Card>

Expand Down Expand Up @@ -276,7 +279,9 @@ const otherRestriction = ref(false);
const alternateEmail = ref(false);
const alternateEmailValue = ref("");

// this is basically an enum: either "success", "failed", or "pending"
const submissionStatus = ref('pending');

const saveStatus = ref("");

const receivingEmails = ref(true);
Expand Down Expand Up @@ -359,6 +364,11 @@ const submitForm = async () => {
}
}

const deregister = async () => {
await User.withdrawRegistration();
submissionStatus.value = "pending";
}

</script>

<style scoped lang="scss">
Expand Down Expand Up @@ -415,4 +425,13 @@ const submitForm = async () => {
border: 1px solid white;
border-radius: 5px;
}

.action-buttons {
display: flex;
gap: 0.5rem;
@media (max-width: 700px) {
flex-direction: column;
align-items: center;
}
}
</style>
94 changes: 73 additions & 21 deletions staff-frontend/pages/index.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, { useState, useEffect, useMemo } from "react";
import React, { useState, useEffect } from "react";
import KHELayout from "../layouts/layout.jsx";
import { remult } from "remult";
import { Email, EmailSource } from "../../global-includes/email-address.ts";
import { Card, Col, Layout, Row, Skeleton, Statistic } from "antd";
import { Email } from "../../global-includes/email-address.ts";
import { Card, Layout, Row, Skeleton, Statistic } from "antd";
import { User } from "../../global-includes/users.ts";
import Link from "next/link.js";
import { Bar, BarChart, CartesianGrid, Legend, Tooltip, XAxis, YAxis } from "recharts";
import { Bar, BarChart, CartesianGrid, Line, LineChart, Tooltip, XAxis, YAxis } from "recharts";

const { Sider, Content } = Layout;

Expand Down Expand Up @@ -53,27 +53,75 @@ const UsersBarChart = () => {
</BarChart>
</Skeleton>
)
}
};

function HomePage() {
const UsersLineGraph = () => {

const [loading, setLoading] = useState(false);
const [chart, setChart] = useState({});

useEffect(() => {

const repo = remult.repo(User);

const loadChart = async () => {

const dataPoints = 20;

const earliest = (await repo.findFirst()).createdAt;
const now = new Date();
const range = now.getTime() - earliest.getTime();
const rangeBetweenPoints = range / (dataPoints - 1);

const points = [{name: earliest.toLocaleDateString(), amount: 0}];
for (let i = 1; i < dataPoints; ++i) {
const before = new Date(earliest.getTime() + i * rangeBetweenPoints);
const count = await repo.count({ createdAt: { $lt: before } });
points.push({
name: before.toLocaleDateString(),
amount: count
});
}

setChart(points);
setLoading(false);
}

setLoading(true);
loadChart();
}, []);

return (
<Skeleton loading={loading} active >
<LineChart width={500} height={400} data={chart}>
<CartesianGrid strokeDasharray="4 4" />
<XAxis dataKey="name" interval="preserveStartEnd" />
<YAxis label={{value: "User Accounts Created", angle: -90}} />
<Tooltip />
<Line dataKey="amount" name="Users" />
</LineChart>
</Skeleton>
)
};

function HomePage() {

const [loadingCounts, setLoadingCounts] = useState(false);
const [counts, setCounts] = useState(null);
const [chart, setChart] = useState([]);

useEffect(() => {

const loadCounts = async () => {
setCounts({
emails: await remult.repo(Email).count(),
early: await Email.getEmailList(EmailSource.Early2023).then(l => l.length),
users: await remult.repo(User).count()
users: await remult.repo(User).count(),
accepted: await remult.repo(User).count({applicationApproved: true})
});

setLoading(false);
setLoadingCounts(false);
}

setLoading(true);
setLoadingCounts(true);
loadCounts();

}, []);
Expand All @@ -85,22 +133,26 @@ function HomePage() {
<Sider width={200} theme="light">
<Layout>
<DBCard>
<Statistic loading={loading} title="2023 Email Signups" value={counts?.early} />
</DBCard>
<DBCard>
<Statistic loading={loading} title={<Link href="/emailLists">Total Email Addresses In DB</Link>} value={counts?.emails} />
<Statistic
loading={loadingCounts}
title={<Link href="/users">User Accounts</Link>}
value={counts?.users}
/>
</DBCard>
<DBCard>
<Statistic loading={loading} title={<Link href="/users">User Accounts</Link>} value={counts?.users} />
<Statistic
loading={loadingCounts}
title={<Link href="/users">Accepted Applications</Link>}
value={counts?.accepted}
/>
</DBCard>
</Layout>
</Sider>
<Content>
<Layout loading={loading} style={{ padding: "10px" }}>
<Row>
<Col xs={{ span: 5, offset: 1 }} lg={{ span: 6, offset: 2 }}>
<UsersBarChart />
</Col>
<Layout loading={loadingCounts} style={{ padding: "10px" }}>
<Row style={{flexWrap: "nowrap", minWidth: 800}}>
<UsersLineGraph />
<UsersBarChart />
</Row>
</Layout>
</Content>
Expand Down
2 changes: 1 addition & 1 deletion staff-frontend/pages/tickets.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useState, useEffect, useMemo, useRef } from "react";
import { SupportTicket, SupportTicketController, TicketMessage, TicketStatus } from "../../global-includes/support-ticket";
import { remult } from "remult";
import { useQueryState } from "next-usequerystate";
import { useQueryState } from "nuqs";
import { Layout, Menu, Button, Popconfirm, Badge, Form, Switch, Input } from "antd";
const { Sider } = Layout;
const { TextArea } = Input;
Expand Down
Loading

0 comments on commit 803654f

Please sign in to comment.