Compare commits

..

25 Commits

Author SHA1 Message Date
9c41b11c4c Adding the initial poll detail pages 2026-01-25 19:46:28 -05:00
b39a094d92 Fixing up the go code, adding initial work for the stats pages, adding a function to pre-populate the database with some example polls for testing. Will be removed later 2026-01-25 19:45:56 -05:00
8b5940741c Merge pull request 'Adding page to create votes and view the votes, rearanging some methods' (#21) from create-vote into main
Reviewed-on: #21
2026-01-23 19:07:14 +00:00
3b0a8625bc Adding page to create votes and view the votes, rearanging some methods 2026-01-23 13:54:05 -05:00
0f6e8a8350 Adding page to view currently uploaded members, as well as verifying admin is logged in 2026-01-22 15:31:36 -05:00
81ccc3035b Adding page to view currently uploaded members, as well as verifying admin is logged in 2026-01-22 15:30:44 -05:00
54dad88ded Merge pull request 'setup-members' (#19) from setup-members into main
Reviewed-on: #19
2026-01-21 19:28:25 +00:00
44326e7d26 Cleaning up main a bit 2026-01-21 14:25:47 -05:00
ce4f8ba7df Better handling of react app 2026-01-21 14:21:11 -05:00
3c489b7c32 First attempt at react interface 2026-01-21 12:51:40 -05:00
5d8977e0c0 Merge pull request 'setup-api' (#18) from setup-api into main
Reviewed-on: #18
2026-01-20 20:59:15 +00:00
a694a73249 Adding not just the api but also some initial code for posting members 2026-01-20 15:56:21 -05:00
0359efe197 Adding initial code for the main.go as well as initial code for uploading members 2026-01-19 20:03:40 -05:00
6b17c6fddc Merge pull request 'set-vote' (#17) from set-vote into main
Reviewed-on: #17
2025-11-13 00:46:42 +00:00
ab48a68fab Deleting questions and adding tests for deleteing 2025-11-12 19:29:13 -05:00
65c5b9611c Adding tests for adding votes 2025-11-12 16:11:39 -05:00
249dbbd603 Adding tests for adding votes 2025-11-12 16:08:54 -05:00
e6fb41b32d Merge pull request 'Get Poll data from database' (#14) from get-poll-by-question into main
Reviewed-on: #14
2025-11-06 18:46:31 +00:00
ff365cec0d Adding more tests for adding a poll if it doesn't exist on get, Adding code to update votes 2025-11-06 13:38:56 -05:00
8fa1947214 Adding tests for getting poll data 2025-11-05 16:18:06 -05:00
711e77e8b8 Merge pull request 'Newpoll Backend' (#12) from create-new-poll-backend into main
Reviewed-on: #12
2025-11-05 20:48:15 +00:00
bae776d845 Merge branch 'main' into create-new-poll-backend 2025-11-05 20:48:05 +00:00
7ad8a1bcc6 More robust testing 2025-11-05 15:47:26 -05:00
5d579781a8 More robust testing 2025-11-04 17:16:42 -05:00
5e8b4e2b61 Adding initial code for adding a new poll on the backend 2025-11-04 16:39:10 -05:00
53 changed files with 20040 additions and 69 deletions

1
.env Normal file
View File

@@ -0,0 +1 @@
db_path="pta_vote.db"

32
.gitignore vendored
View File

@@ -22,6 +22,34 @@
go.work go.work
go.work.sum go.work.sum
# env file # ---> React & npm
.env node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# ---> NPM cache
.npmrc
# ---> Webpack
dist/
build/
# ---> Babel
.babelrc
babel.config.js
# ---> ESLint
.eslintrc
.eslintignore
eslintcache.js
# ---> Prettier
.prettierrc
prettierignore
# ---> Jest
coverage/
jest.config.js

23
client/.gitignore vendored Normal file
View File

@@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

16720
client/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

42
client/package.json Normal file
View File

@@ -0,0 +1,42 @@
{
"name": "client",
"version": "0.1.0",
"private": true,
"dependencies": {
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@mui/icons-material": "^7.3.7",
"@mui/material": "^7.3.7",
"axios": "^1.13.2",
"cra-template-pwa": "2.0.0",
"react": "^19.2.3",
"react-dom": "^19.2.3",
"react-router": "7.12.0",
"react-scripts": "5.0.1",
"recharts": "^3.7.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

BIN
client/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

40
client/public/index.html Normal file
View File

@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Web site created using create-react-app" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

BIN
client/public/logo192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
client/public/logo512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -0,0 +1,25 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

3
client/public/robots.txt Normal file
View File

@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

73
client/src/App.css Normal file
View File

@@ -0,0 +1,73 @@
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.dropdown {
display: inline-block;
}
.dropbtn {
background-color: #f5f5f5;
border: none;
cursor: pointer;
}
.dropdown-content {
display: none; /* Hidden by default */
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
/* Show the dropdown menu on hover */
.dropdown:hover .dropdown-content {
display: block;
}
/* Add zebra striping to tables */
table tr:nth-child(odd) {
background-color: #f5f5f5;
}

49
client/src/App.js Normal file
View File

@@ -0,0 +1,49 @@
import React from "react";
import { BrowserRouter, Routes, Route, Link } from "react-router";
import Home from "./pages/Home";
import AdminLogin from "./pages/AdminLogin";
import AdminMembers from "./pages/AdminMembers";
import AdminMembersView from "./pages/AdminMembersView";
import AdminCreateVote from "./pages/AdminCreateVote";
import PollList from "./pages/PollList";
import PollDetails from "./pages/PollDetails";
import './App.css';
export default function App() {
return (
<BrowserRouter>
<nav style={{ padding: "1rem", background: "#f5f5f5" }}>
<Link to="/">Home</Link> |
<Link to="/admin-login">Admin Login</Link> |
{/* Member dropdown */}
<div className="dropdown">
<button className="dropbtn">Member </button>
<div className="dropdown-content">
<a href="/admin-members">Upload Members</a>
<a href="/admin-members-view">View Members</a>
</div>
</div> |
<div className="dropdown">
<button className="dropbtn">Vote </button>
<div className="dropdown-content">
<a href="/create-vote">Create Vote</a>
<a href="/polls">Poll List</a>
<a href="/poll-details/:id">View Poll Details</a> {/* Add this line */}
</div>
</div>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/admin-login" element={<AdminLogin />} />
{/* Member routes */}
<Route path="/admin-members" element={<AdminMembers />} />
<Route path="/admin-members-view" element={<AdminMembersView />} />
{/* Vote routes */}
<Route path="/create-vote" element={<AdminCreateVote />} />
<Route path="/polls" element={<PollList />} />
<Route path="/poll-details/:id" element={<PollDetails />} /> {/* Add this route */}
</Routes>
</BrowserRouter>
);
}

9
client/src/App.test.js Normal file
View File

@@ -0,0 +1,9 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

13
client/src/index.css Normal file
View File

@@ -0,0 +1,13 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}

7
client/src/index.js Normal file
View File

@@ -0,0 +1,7 @@
import React from "react";
import { createRoot } from "react-dom/client";
import App from "./App";
import "./index.css"; // optional keep CRA default styling
const container = document.getElementById("root");
createRoot(container).render(<App />);

7
client/src/logo.svg Normal file
View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3">
<g fill="#61DAFB">
<path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/>
<circle cx="420.9" cy="296.5" r="45.7"/>
<path d="M520.5 78.1z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1,67 @@
import React, { useState } from 'react';
function AdminCreateVote() {
const [question, setQuestion] = useState('');
const [expiresInHours, setExpiresInHours] = useState('');
const [status, setStatus] = useState("");
const handleSubmit = async (e) => {
e.preventDefault();
const formData = new FormData();
formData.append("question", question);
formData.append("expiresInHours", expiresInHours);
try {
const resp = await fetch("/api/admin/new-vote", {
method: "POST",
body: formData,
});
const data = await resp.json();
if (data.success) {
setStatus(`✅ Vote created with ID`);
} else {
setStatus(`❌ Server error: ${data.error}`);
}
} catch (error) {
setStatus("❌ Failed to create vote. Please try again: " + (error.response?.data?.error || error.message));
}
};
return (
<div>
<h1>Create New Vote</h1>
<form onSubmit={handleSubmit}>
<div>
<label>Question:</label>
<input
type="text"
value={question}
onChange={(e) => setQuestion(e.target.value)}
required
/>
</div>
<div>
<label>Expires In (hours):</label>
<input
type="number"
min="1"
value={expiresInHours}
onChange={(e) => setExpiresInHours(e.target.value)}
required
/>
</div>
<button type="submit">Create Vote</button>
</form>
{status && <p style={{ marginTop: "1rem" }}>{status}</p>}
</div>
);
}
export default AdminCreateVote;

View File

@@ -0,0 +1,137 @@
import React, { useState } from "react";
import { useNavigate } from "react-router";
export default function AdminLogin() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const [isLoading, setIsLoading] = useState(false);
const navigate = useNavigate();
const handleSubmit = async (e) => {
e.preventDefault();
setError("");
setIsLoading(true);
if (!username || !password) {
setError("⚠️ Please enter both username and password.");
setIsLoading(false);
return;
}
try {
const resp = await fetch("/api/admin/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
username,
password,
}),
});
const data = await resp.json();
if (resp.ok && data.success) {
// Store the auth token in localStorage
localStorage.setItem("adminToken", data.token);
setError("");
navigate("/admin-members");
} else {
setError(`${data.error || "Login failed"}`);
}
} catch (err) {
setError(`❌ Network error: ${err.message}`);
} finally {
setIsLoading(false);
}
};
return (
<div
style={{
padding: "2rem",
maxWidth: "400px",
margin: "5rem auto",
border: "1px solid #ddd",
borderRadius: "8px",
boxShadow: "0 2px 4px rgba(0,0,0,0.1)",
}}
>
<h2 style={{ textAlign: "center", marginBottom: "2rem" }}>Admin Login</h2>
<form onSubmit={handleSubmit}>
<div style={{ marginBottom: "1rem" }}>
<label htmlFor="username">Username:</label>
<input
id="username"
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
style={{
width: "100%",
padding: "0.5rem",
marginTop: "0.5rem",
border: "1px solid #ccc",
borderRadius: "4px",
boxSizing: "border-box",
}}
placeholder="Enter your username"
/>
</div>
<div style={{ marginBottom: "1.5rem" }}>
<label htmlFor="password">Password:</label>
<input
id="password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
style={{
width: "100%",
padding: "0.5rem",
marginTop: "0.5rem",
border: "1px solid #ccc",
borderRadius: "4px",
boxSizing: "border-box",
}}
placeholder="Enter your password"
/>
</div>
{error && (
<div
style={{
padding: "1rem",
marginBottom: "1rem",
backgroundColor: "#ffe0e0",
border: "1px solid #ff6b6b",
borderRadius: "4px",
color: "#c92a2a",
}}
>
{error}
</div>
)}
<button
type="submit"
disabled={isLoading}
style={{
width: "100%",
padding: "0.75rem",
backgroundColor: isLoading ? "#ccc" : "#007bff",
color: "white",
border: "none",
borderRadius: "4px",
cursor: isLoading ? "not-allowed" : "pointer",
fontSize: "1rem",
fontWeight: "bold",
}}
>
{isLoading ? "Logging in..." : "Login"}
</button>
</form>
</div>
);
}

View File

@@ -0,0 +1,95 @@
import React, { useState, useEffect } from "react";
import { useNavigate } from 'react-router';
export default function AdminMembers() {
const [year, setYear] = useState("");
const [file, setFile] = useState(null);
const [status, setStatus] = useState("");
const navigate = useNavigate();
const isAdmin = () => {
return localStorage.getItem('adminToken') !== null;
};
if (!isAdmin()) {
navigate('/admin-login');
return <div>Redirecting...</div>;
}
const handleSubmit = async (e) => {
e.preventDefault();
if (!year) {
setStatus("⚠️ Please enter a year.");
return;
}
if (!file) {
setStatus("⚠️ Please select a CSV file.");
return;
}
const formData = new FormData();
formData.append("year", year);
formData.append("members.csv", file); // name must match the Go handler
try {
const resp = await fetch("/api/admin/members", {
method: "POST",
body: formData,
});
const data = await resp.json();
if (data.success) {
setStatus(`✅ Uploaded!`);
} else {
setStatus(`❌ Server error: ${data.error}`);
}
} catch (err) {
setStatus(`❌ Network error: ${err.message}`);
}
};
return (
<div style={{ padding: "2rem" }}>
<h2>Upload Members CSV</h2>
<form onSubmit={handleSubmit}>
<div style={{ marginBottom: "1rem" }}>
<label htmlFor="year">Year:</label>
<input
type="number"
id="year"
name="year"
value={year}
onChange={(e) => setYear(e.target.value)}
required
min="1900"
max="2100"
style={{ width: "150px", padding: "0.3rem" }}
/>
</div>
<div style={{ marginBottom: "1rem" }}>
<label htmlFor="members.csv">CSV File:</label>
<input
type="file"
id="members.csv"
name="members.csv"
accept=".csv"
onChange={(e) => setFile(e.target.files[0])}
required
/>
</div>
<button type="submit" style={{ padding: "0.5rem 1rem" }}>
Upload
</button>
</form>
{status && <p style={{ marginTop: "1rem" }}>{status}</p>}
</div>
);
}

View File

@@ -0,0 +1,85 @@
import React, { useState } from "react";
import { useNavigate } from 'react-router';
import Table from '@mui/material/Table';
export default function AdminMembersView() {
const [year, setYear] = useState("");
const [members, setMembers] = useState([]);
const [status, setStatus] = useState("");
const navigate = useNavigate();
const isAdmin = () => {
return localStorage.getItem('adminToken') !== null;
};
if (!isAdmin()) {
navigate('/admin-login');
return <div>Redirecting...</div>;
}
const handleSubmit = async (e) => {
e.preventDefault();
try {
const resp = await fetch(`/api/admin/members/view?year=${year}`);
const data = await resp.json();
if (data.success) {
setMembers(data.members);
} else {
setStatus(`❌ Server error: ${data.error}`);
}
} catch (err) {
setStatus(`❌ Network error: ${err.message}`);
}
};
return (
<div style={{ padding: "2rem" }}>
<h2>View Members</h2>
<form onSubmit={handleSubmit}>
<div style={{ marginBottom: "1rem" }}>
<label htmlFor="year">Year:</label>
<input
type="number"
id="year"
name="year"
value={year}
onChange={(e) => setYear(e.target.value)}
required
min="1900"
max="2100"
style={{ width: "150px", padding: "0.3rem" }}
/>
</div>
<button type="submit" style={{ padding: "0.5rem 1rem" }}>
View Members
</button>
</form>
{members.length > 0 && (
<Table>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
</tr>
</thead>
<tbody>
{members.map((member, index) => (
<tr key={index}>
<td>{member.Name}</td>
<td>{member.Email}</td>
</tr>
))}
</tbody>
</Table>
)}
{status && <p style={{ marginTop: "1rem" }}>{status}</p>}
</div>
);
}

8
client/src/pages/Home.js Normal file
View File

@@ -0,0 +1,8 @@
export default function Home() {
return (
<div style={{ padding: "2rem" }}>
<h1>Welcome!</h1>
<p>This is the landing page. Use the navigation bar to go to the admin page.</p>
</div>
);
}

View File

@@ -0,0 +1,92 @@
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import {
PieChart,
Pie,
Cell,
Tooltip,
Legend,
} from 'recharts';
const COLORS = ['#0088FE', '#FEB43C'];
export default function PollDetail({ question }) {
const [poll, setPoll] = useState(null);
useEffect(() => {
fetchPoll();
}, [question]);
const fetchPoll = async () => {
try {
const response = await axios.post('/api/admin/view-votes', { question });
setPoll(response.data[0]);
} catch (error) {
console.error('Error fetching poll:', error);
}
};
if (!poll) return <div>Loading...</div>;
const memberData = [
{ name: 'Yes', value: poll.member_yes },
{ name: 'No', value: poll.member_no },
];
const nonMemberData = [
{ name: 'Yes', value: poll.non_member_yes },
{ name: 'No', value: poll.non_member_no },
];
return (
<div>
<h1>{poll.question}</h1>
<p>Created At: {new Date(poll.created_at).toLocaleString()}</p>
<div style={{ width: '40%', margin: '20px' }}>
<PieChart width={400} height={300}>
<Pie
data={memberData}
cx="50%"
cy="50%"
labelLine={false}
outerRadius={80}
fill="#8884d8"
dataKey="value"
>
{memberData.map((entry, index) => (
<Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
))}
</Pie>
<Tooltip />
<Legend />
</PieChart>
</div>
<div style={{ width: '40%', margin: '20px' }}>
<PieChart width={400} height={300}>
<Pie
data={nonMemberData}
cx="50%"
cy="50%"
labelLine={false}
outerRadius={80}
fill="#8884d8"
dataKey="value"
>
{nonMemberData.map((entry, index) => (
<Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
))}
</Pie>
<Tooltip />
<Legend />
</PieChart>
</div>
<p>Member Yes Votes: {poll.member_yes}</p>
<p>Member No Votes: {poll.member_no}</p>
<p>Non-Member Yes Votes: {poll.non_member_yes}</p>
<p>Non-Member No Votes: {poll.non_member_no}</p>
</div>
);
}

View File

@@ -0,0 +1,103 @@
import React, { useState, useEffect } from "react";
import axios from 'axios';
import {
PieChart,
Pie,
Tooltip,
Legend,
Cell,
} from 'recharts';
const COLORS = ['#0088FE', '#FEB43C'];
export default function PollDetails() {
const [poll, setPoll] = useState(null);
const [loading, setLoading] = useState(true);
// Get poll ID from URL parameters
const match = window.location.pathname.match(/\/poll-details\/(\d+)/);
const pollId = match ? parseInt(match[1], 10) : null;
useEffect(() => {
if (pollId) {
fetchPollDetails(pollId);
}
}, [pollId]);
const fetchPollDetails = async (id) => {
try {
setLoading(true);
const response = await axios.post(`/api/poll/${id}`);
setPoll(response.data);
} catch (error) {
console.error('Error fetching poll details:', error);
} finally {
setLoading(false);
}
};
if (loading || !poll) return <div>Loading...</div>;
// Define data for pie charts
const memberData = [
{ name: 'Yes', value: poll.member_yes },
{ name: 'No', value: poll.member_no }
];
const nonMemberData = [
{ name: 'Yes', value: poll.non_member_yes },
{ name: 'No', value: poll.non_member_no }
];
return (
<div className="poll-details">
<h1>{poll.question}</h1>
<p>Created At: {new Date(poll.created_at).toLocaleString()}</p>
<div style={{ width: '40%', margin: '20px' }}>
<PieChart width={400} height={300}>
<Pie
data={memberData}
cx="50%"
cy="50%"
labelLine={false}
outerRadius={80}
fill="#8884d8"
dataKey="value"
>
{memberData.map((entry, index) => (
<Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
))}
</Pie>
<Tooltip />
<Legend />
</PieChart>
</div>
<div style={{ width: '40%', margin: '20px' }}>
<PieChart width={400} height={300}>
<Pie
data={nonMemberData}
cx="50%"
cy="50%"
labelLine={false}
outerRadius={80}
fill="#8884d8"
dataKey="value"
>
{nonMemberData.map((entry, index) => (
<Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
))}
</Pie>
<Tooltip />
<Legend />
</PieChart>
</div>
<p>Member Yes Votes: {poll.member_yes}</p>
<p>Member No Votes: {poll.member_no}</p>
<p>Non-Member Yes Votes: {poll.non_member_yes}</p>
<p>Non-Member No Votes: {poll.non_member_no}</p>
</div>
);
}

View File

@@ -0,0 +1,33 @@
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import { Link } from 'react-router';
export default function PollList() {
const [polls, setPolls] = useState([]);
useEffect(() => {
fetchPolls();
}, []);
const fetchPolls = async () => {
try {
const response = await axios.post('/api/admin/view-votes');
setPolls(response.data);
} catch (error) {
console.error('Error fetching polls:', error);
}
};
return (
<div className="poll-list">
<h1>Poll List</h1>
{polls.map((poll) => (
<div key={poll.id} className="poll-item">
<Link to={`/poll-details/${poll.id}`}>
<h2>{poll.question}</h2>
</Link>
</div>
))}
</div>
);
}

View File

@@ -0,0 +1,13 @@
const reportWebVitals = (onPerfEntry) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};
export default reportWebVitals;

View File

@@ -0,0 +1,72 @@
/* eslint-disable no-restricted-globals */
// This service worker can be customized!
// See https://developers.google.com/web/tools/workbox/modules
// for the list of available Workbox modules, or add any other
// code you'd like.
// You can also remove this file if you'd prefer not to use a
// service worker, and the Workbox build step will be skipped.
import { clientsClaim } from 'workbox-core';
import { ExpirationPlugin } from 'workbox-expiration';
import { precacheAndRoute, createHandlerBoundToURL } from 'workbox-precaching';
import { registerRoute } from 'workbox-routing';
import { StaleWhileRevalidate } from 'workbox-strategies';
clientsClaim();
// Precache all of the assets generated by your build process.
// Their URLs are injected into the manifest variable below.
// This variable must be present somewhere in your service worker file,
// even if you decide not to use precaching. See https://cra.link/PWA
precacheAndRoute(self.__WB_MANIFEST);
// Set up App Shell-style routing, so that all navigation requests
// are fulfilled with your index.html shell. Learn more at
// https://developers.google.com/web/fundamentals/architecture/app-shell
const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$');
registerRoute(
// Return false to exempt requests from being fulfilled by index.html.
({ request, url }) => {
// If this isn't a navigation, skip.
if (request.mode !== 'navigate') {
return false;
} // If this is a URL that starts with /_, skip.
if (url.pathname.startsWith('/_')) {
return false;
} // If this looks like a URL for a resource, because it contains // a file extension, skip.
if (url.pathname.match(fileExtensionRegexp)) {
return false;
} // Return true to signal that we want to use the handler.
return true;
},
createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html')
);
// An example runtime caching route for requests that aren't handled by the
// precache, in this case same-origin .png requests like those from in public/
registerRoute(
// Add in any other file extensions or routing criteria as needed.
({ url }) => url.origin === self.location.origin && url.pathname.endsWith('.png'), // Customize this strategy as needed, e.g., by changing to CacheFirst.
new StaleWhileRevalidate({
cacheName: 'images',
plugins: [
// Ensure that once this runtime cache reaches a maximum size the
// least-recently used images are removed.
new ExpirationPlugin({ maxEntries: 50 }),
],
})
);
// This allows the web app to trigger skipWaiting via
// registration.waiting.postMessage({type: 'SKIP_WAITING'})
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});
// Any other custom service worker logic can go here.

View File

@@ -0,0 +1,137 @@
// This optional code is used to register a service worker.
// register() is not called by default.
// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on subsequent visits to a page, after all the
// existing tabs open on the page have been closed, since previously cached
// resources are updated in the background.
// To learn more about the benefits of this model and instructions on how to
// opt-in, read https://cra.link/PWA
const isLocalhost = Boolean(
window.location.hostname === 'localhost' ||
// [::1] is the IPv6 localhost address.
window.location.hostname === '[::1]' ||
// 127.0.0.0/8 are considered localhost for IPv4.
window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
);
export function register(config) {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
// The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
if (publicUrl.origin !== window.location.origin) {
// Our service worker won't work if PUBLIC_URL is on a different origin
// from what our page is served on. This might happen if a CDN is used to
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
return;
}
window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
if (isLocalhost) {
// This is running on localhost. Let's check if a service worker still exists or not.
checkValidServiceWorker(swUrl, config);
// Add some additional logging to localhost, pointing developers to the
// service worker/PWA documentation.
navigator.serviceWorker.ready.then(() => {
console.log(
'This web app is being served cache-first by a service ' +
'worker. To learn more, visit https://cra.link/PWA'
);
});
} else {
// Is not localhost. Just register service worker
registerValidSW(swUrl, config);
}
});
}
}
function registerValidSW(swUrl, config) {
navigator.serviceWorker
.register(swUrl)
.then((registration) => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
if (installingWorker == null) {
return;
}
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// At this point, the updated precached content has been fetched,
// but the previous service worker will still serve the older
// content until all client tabs are closed.
console.log(
'New content is available and will be used when all ' +
'tabs for this page are closed. See https://cra.link/PWA.'
);
// Execute callback
if (config && config.onUpdate) {
config.onUpdate(registration);
}
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// "Content is cached for offline use." message.
console.log('Content is cached for offline use.');
// Execute callback
if (config && config.onSuccess) {
config.onSuccess(registration);
}
}
}
};
};
})
.catch((error) => {
console.error('Error during service worker registration:', error);
});
}
function checkValidServiceWorker(swUrl, config) {
// Check if the service worker can be found. If it can't reload the page.
fetch(swUrl, {
headers: { 'Service-Worker': 'script' },
})
.then((response) => {
// Ensure service worker exists, and that we really are getting a JS file.
const contentType = response.headers.get('content-type');
if (
response.status === 404 ||
(contentType != null && contentType.indexOf('javascript') === -1)
) {
// No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then((registration) => {
registration.unregister().then(() => {
window.location.reload();
});
});
} else {
// Service worker found. Proceed as normal.
registerValidSW(swUrl, config);
}
})
.catch(() => {
console.log('No internet connection found. App is running in offline mode.');
});
}
export function unregister() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready
.then((registration) => {
registration.unregister();
})
.catch((error) => {
console.error(error.message);
});
}
}

5
client/src/setupTests.js Normal file
View File

@@ -0,0 +1,5 @@
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';

330
example_members.csv Normal file
View File

@@ -0,0 +1,330 @@
"Joined At","First Name","Last Name","Email","Mobile","Member Type","Check Number","Type","Year","Price Paid","Status","student_1_grade","student_1_full_name","Would you like to be added to a no-obligation volunteer email list?","Student 1 Grade","Student 1 Full Name","Would you like to be added to a no-obligation volunteer list?","Would you like a car magnet as a thank you for your generous donation?","student_2_grade","student_2_full_name","student_4_full_name","student_3_full_name","Student 2 Grade","Student 2 Full Name","student_3_grade","student_1_grade_level","student_2_grade_level","Member_2_-_Email","Member_2_-_Last name","Member_2_-_First name"
"02/07/2023 at 4:53 pm","Alexandria","Capecci ","alexandria_capecci@hcpss.org","","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","",""
"01/25/2023 at 3:48 pm","Pamela","Buzzerd","pamelabuzzerd@gmail.com","3014664634","Grandparent","","Store Purchase","2022 - 2023","$10.00","","1","Allison Buzzerd","Yes","","","","","","","","","",""
"12/29/2022 at 5:04 pm","Anthony","Kattukaran","anthonykattukaran@yahoo.com","6086283259","Parent/Guardian","","Store Purchase","2022 - 2023","$75.00","","","","","4","George Kattukaran","No","Yes","","","","","",""
"12/14/2022 at 9:06 pm","Phaedra","Larner","Plarner@hcpss.org","4109487215","Faculty/Staff","","Store Purchase","2022 - 2023","$12.00","","","","Yes","1","Phaedra Larner","","","","","","","",""
"11/21/2022 at 1:17 pm","Jennifer","Lowney","jennifer_lowney@hcpss.org","4104043012","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","",""
"11/16/2022 at 8:05 pm","Cith","Nadarajah","Cithparan@gmail.com","4109257631","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Abira Nadarajah","Yes","","","","","2","Aashna Nadarajah","","","",""
"11/16/2022 at 8:05 pm","Sudha","Nadarajah","ss849319@gmail.com","443-841-9319","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Abira Nadarajah","Yes","","","","","2","Aashna Nadarajah","","","",""
"11/09/2022 at 8:59 am","Jane","Derro","Jderro@hcpss.org","443 535 3179","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","",""
"11/03/2022 at 4:13 pm","Phaedra","Larner","Plarner@hotmail.com","410-948-7215","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","",""
"10/26/2022 at 8:13 am","Lina","Chauhan-Klein","lina_chauhan-klein1@hcpss.org","2406547886","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","",""
"10/21/2022 at 9:38 pm","Caroline","Chisholm","carolinewchisholm@gmail.com","","Parent/Guardian","","Cash","2022 - 2023","$30.00","","","","Yes","1","Connor Chisholm","","","","","","","",""
"10/21/2022 at 9:33 pm","Kathleen","Newberry","kathleen_newberry@hcpss.org","","Faculty/Staff","","Cash","2022 - 2023","$10.00","","","","","","","","","","","","","",""
"10/21/2022 at 9:32 pm","Jen","Alexander","jennifer_alexander1@hcpss.org","","Faculty/Staff","","Cash","2022 - 2023","$10.00","","","","","","","","","","","","","",""
"10/21/2022 at 11:33 am","Elizabeth","Shoff","E.ULBRECHT@GMAIL.COM","8147777444","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","",""
"10/20/2022 at 9:03 am","Carl","Frantz","carl_frantz@hcpss.org","2405060888","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","",""
"10/20/2022 at 9:01 am","Elizabeth","Carty","Elizabeth_carty@hcpss.org","2402103520","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","",""
"10/19/2022 at 2:58 pm","Rebecca","Whitaker","Rebecca_Whitaker@hcpss.org","","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","",""
"10/18/2022 at 4:09 pm","Nancy","Carter","nancy_carter@hcpss.org","","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","",""
"10/12/2022 at 4:32 pm","Katherine","Etheridge","i8that2@gmail.com","4107502168","Parent/Guardian","","Store Purchase","2022 - 2023","$75.00","","","","","4","Arianna Delaney","Yes","No","","","","","",""
"10/12/2022 at 1:13 pm","Jimmy","Kwak","Kwak.james@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","1","Henry Kwak","No","","","","No","","","","","",""
"10/12/2022 at 1:13 pm","Jennifer","Kwak","jennifer.y.kwak@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","1","Henry Kwak","Yes","","","","No","","","","","",""
"10/12/2022 at 8:58 am","Scott ","Moore ","Roastedsmoores@gmail.com","3013468777","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","2","Filomena Moore ","No","","","","No","","","","","",""
"10/12/2022 at 8:58 am","Lara","Moore","lara.paolini@gmail.com","3013468777","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","2","Filomena Moore ","No","","","","No","5","Desmond Moore ","","","",""
"10/08/2022 at 3:21 pm","Peggy","Fredriksson","Margaret_fredriksson@hcpss.org","","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","",""
"10/05/2022 at 12:39 pm","Alexis","Kalivretenos","alexis_kalivretenos@hcpss.org","443-765-0907","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","",""
"10/04/2022 at 9:57 pm","Jean","Austin","jean_austin@hcpss.org","","Faculty/Staff","","Cash","2022 - 2023","$10.00","","","","","","","","","","","","","",""
"10/04/2022 at 3:03 pm","Chelsea","Berube","chelsea_berube@hcpss.org","","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","",""
"10/02/2022 at 9:30 pm","Chunling","Zhao","Chunlingzhao@hotmail.com","2406201699","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","1","Nathan Lu","Yes","","","","Yes","5","Andy Lu","","","",""
"10/02/2022 at 9:30 pm","Qijin","Lu","qijinlu@yahoo.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","1","Nathan Lu","Yes","","","","Yes","","Andy Lu","Chunking Zhao","","",""
"10/01/2022 at 3:34 pm","Derek ","Easter","deaste1@hotmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","3","Mabel Easter","No","","","","No","1","James Easter","","","",""
"10/01/2022 at 3:34 pm","Carissa","Easter","carissaeaster@gmail.com","4439043176","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","3","Mabel Easter","Yes","","","","No","1","James Easter","","","",""
"09/30/2022 at 8:53 am","Jason","Drenner","drennerjason@gmail.com","3018754226","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","1","Rhyze Drenner","Yes","","","","No","3","Joules Drenner","","","",""
"09/30/2022 at 8:53 am","Amber ","Drenner","amber.drenner@uwcm.org","4107037019","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","1","Amber M Drenner","Yes","","","","No","3","Rhyze Anjuli Drenner","Jason Drenner","Joules Epifania Drenner","",""
"09/27/2022 at 9:49 am","Andrew","Dain","Andyd1@gmail.com","4102411005","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","3","Eli Dain","Yes","","","","No","","","","","",""
"09/27/2022 at 9:49 am","Renee ","Dain ","renee.dain@gmail.com","4102078276","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","3","Eli Dain","Yes","","","","Yes","","","","","",""
"09/26/2022 at 10:22 pm","Kim","Cofsky","kimberlycofsky@gmail.com","","Parent/Guardian","","Cash","2022 - 2023","$30.00","","","","Yes","1","Nora Cofsky","","","","","","","",""
"09/26/2022 at 10:20 pm","Asra","Khatoon ","asramajid1710@gmail.com","","Parent/Guardian","","Cash","2022 - 2023","$12.00","","","","Yes","2","Yousuf Majid","","","","","","","1","Zoya Majid"
"09/23/2022 at 3:57 pm","Robert","Holsopple","","4108492914","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Henry Holsopple","Yes","","","","Yes","","","","","",""
"09/23/2022 at 3:57 pm","Carrie","Baran","baran.holsopple@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Henry Holsopple","Yes","","","","Yes","","","","","",""
"09/22/2022 at 12:32 pm","Shannon","Kennedy","Shannon_kennedy@hcpss.org","4107074913","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","",""
"09/21/2022 at 2:37 pm","Jack","Morton","jmorton96@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Anna Morton ","No","","","","","","","","","",""
"09/21/2022 at 2:37 pm","Tiffany","Preddy","tgpreddy@yahoo.com","5122936323","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Anna Morton","Yes","","","","","","","","","",""
"09/21/2022 at 11:20 am","Elizabeth","Stern","lizandscottwed2013@gmail.com","6174135512","Parent/Guardian","","Store Purchase","2022 - 2023","$12.00","","","","Yes","2","Andrew Stern","","","","","","","2","Gabriel Stern"
"09/20/2022 at 8:41 pm","Swetha","Enaganti","swethae@gmail.com","","Parent/Guardian","","Cash","2022 - 2023","$12.00","","","","Yes","5","Adhvaita Chandar","","","","","","","1","Eshwar Chandar"
"09/19/2022 at 1:47 pm","Diana","Zhuravel","dina.zhuravel@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$12.00","","","","Yes","3","Joshua Zhuravel ","","","","","","","",""
"09/18/2022 at 8:22 pm","Ken","Ng","kennethngdo@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Nora Ng","No","","","","No","","","","","",""
"09/18/2022 at 8:22 pm","Elizabeth","Taylor","elizabeth.taylor16@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Nora Ng","Yes","","","","No","","","","","",""
"09/17/2022 at 9:07 pm","Michael","Mayfield","mmfield@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Nolan Mayfield","No","","","","No","1","Blythe Mayfield","","","",""
"09/17/2022 at 9:07 pm","Catherine","Mayfield","cate.mayfield@gmail.com","4153062125","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Nolan Mayfield","No","","","","No","1","Blythe Mayfield","","","",""
"09/17/2022 at 4:37 pm","Michelle ","Stein","michelle.l.stein@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$12.00","","","","Yes","4","Farrah Stein","","","","","","","",""
"09/16/2022 at 4:35 pm","Daniel","Becker","danielvarebecker@yahoo.com","301-455-9656","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","Andrew Becker","No","","","","","1","Bryce Becker","","","",""
"09/16/2022 at 4:35 pm","Natasha","Becker","nrbecker08@gmail.com","4104048436","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","Andrew Becker","Yes","","","","","1","Bryce Becker","","","",""
"09/16/2022 at 8:53 am","Tim","Lane","lane.tim2@gmail.com","4104094617","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Patrick Lane","Yes","","","","","1","Jack Lane","","","",""
"09/16/2022 at 8:53 am","Michelle","Lane","michellelane713@gmail.com","6095757873","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Patrick Lane","Yes","","","","","1","Jack Lane","","","",""
"09/16/2022 at 7:27 am","Mike","DeSimone","Mike.DeSimone@gmail.com","","Parent/Guardian","","Cash","2022 - 2023","$50.00","","5","Nathan DeSimone","Yes","","","","No","","","","","",""
"09/16/2022 at 7:27 am","Veronica","DeSimone","VLDeSimone@gmail.com","","Parent/Guardian","487","Check","2022 - 2023","$50.00","","5","Nathan DeSimone","Yes","","","","No","","","","","",""
"09/15/2022 at 9:57 pm","Cindy","Mei-Yip","cindy.x.mei@gmail.com","","Parent/Guardian","128","Check","2022 - 2023","$75.00","","","","","2","Sara Mei Yip","No","Yes","","","","","5","Summer Mei Yip"
"09/15/2022 at 9:55 pm","Wajeeha","Qayyumi","wajeehas198@gmail.com","","Parent/Guardian","","Cash","2022 - 2023","$15.00","","3","Zakariya Shahid","No","","","","","1","Moeez Shahid","","","",""
"09/15/2022 at 9:55 pm","Shahid ","Khursheed","lovebird4u_usa@yahoo.com","","Parent/Guardian","","Cash","2022 - 2023","$15.00","","3","Zakariya Shahid","No","","","","","1","Moeez Shahid","","","",""
"09/15/2022 at 7:49 pm","Joseph","Danquah","jbdan72@hotmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","5","Rhema Danquah","Yes","","","","","","","","","",""
"09/15/2022 at 7:49 pm","Mame","Danquah","mame700@yahoo.com","4104023206","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","5","Rhema Danquah","Yes","","","","","","","","","",""
"09/15/2022 at 6:22 pm","Didier","Monestine","dmonestine@gmail.com","7139270628","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Zoey Monestine","No","","","","","","","","","",""
"09/15/2022 at 6:22 pm","Melondy","Monestine","no.1bizneswoman@gmail.com","4438393761","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Zoey Monestine","Yes","","","","","","","","","",""
"09/15/2022 at 1:43 pm","Ryan","Hikel","hikelrw@gmail.com","4432770566","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Avery Hikel","No","","","","","","","","","",""
"09/15/2022 at 1:43 pm","Stephanie","Hikel","smhikel@gmail.com","4102361226","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Avery Hikel","Yes","","","","","","","","","",""
"09/15/2022 at 10:36 am","James","Stepanek","jjstepanek@hotmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","Ryan Stepanek","Yes","","","","","","","","","",""
"09/15/2022 at 10:36 am","Laura ","Stepanek","lmagurk@hotmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","Ryan Stepanek","Yes","","","","","","","","","",""
"09/15/2022 at 8:33 am","Katie","Coffey","katherine_coffey@hcpss.org","4103002846","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","",""
"09/15/2022 at 7:36 am","Chasity","Thompson","cnmthomp@icloud.com","","Parent/Guardian","1052","Check","2022 - 2023","$75.00","","","","","4","Noa Thompson","No","Yes","","","","","","Nicholas Thompson"
"09/15/2022 at 7:33 am","Bonyoung","Lee","kellygu0121@gmail.com","","Parent/Guardian","","Cash","2022 - 2023","$37.50","","K","Aiden Raon Lee","Yes","","","","Yes","","","","","",""
"09/15/2022 at 7:33 am","Scott","Lee","may4am@gmail.com","","Parent/Guardian","1912","Check","2022 - 2023","$37.50","","K","Aiden Raon Lee","Yes","","","","Yes","","","","","",""
"09/15/2022 at 7:30 am","Allyson","Jackson","ja_jackson@verizon.net","","Parent/Guardian","2940","Check","2022 - 2023","$30.00","","","","Yes","5","Kyle Jackson","","","","","","","",""
"09/15/2022 at 7:26 am","Chris","Bechis","chris.bechis@gmail.com","","Parent/Guardian","","Cash","2022 - 2023","$15.00","","3","June Bechis","Yes","","","","","","","","","",""
"09/15/2022 at 7:26 am","Leslie","Bechis","leslie.bechis@gmail.com","","Parent/Guardian","663","Check","2022 - 2023","$15.00","","3","June Bechis","Yes","","","","","","","","","",""
"09/15/2022 at 7:23 am","Joseph","Greenseid","jgreenseid@gmail.com","","Parent/Guardian","","Cash","2022 - 2023","$15.00","","2","Lily Greenseid","Yes","","","","","","","","","",""
"09/15/2022 at 7:23 am","Jessica","Greenseid","jessica.greenseid@gmail.com","","Parent/Guardian","564","Check","2022 - 2023","$15.00","","2","Lily Greenseid","Yes","","","","","","","","","",""
"09/15/2022 at 7:19 am","Adrian","Loftus","acewx333@hotmail.com","","Parent/Guardian","","Cash","2022 - 2023","$15.00","","4","Diego Loftus","No","","","","","","","","","",""
"09/15/2022 at 7:19 am","Andrea","Loftus","andruloftus@hotmail.com","","Parent/Guardian","","Cash","2022 - 2023","$15.00","","4","Diego Loftus","Yes","","","","","","","","","",""
"09/15/2022 at 7:09 am","Tara","Persaud","tara.persaud31@gmail.com","4434547247","Parent/Guardian","","Store Purchase","2022 - 2023","$12.00","","","","Yes","3","Avery Persaud","","","","","","","",""
"09/14/2022 at 9:47 pm","Jon","Zawodny","jonsawodny@gmail.com","","Parent/Guardian","","Cash","2022 - 2023","$37.50","","2","Olivia Zawodny","Yes","","","","Yes","","","","","",""
"09/14/2022 at 9:47 pm","Vanessa","Zawodny","vanessa.zawodny@gmail.com","","Parent/Guardian","230","Check","2022 - 2023","$37.50","","2","Olivia Zawodny","Yes","","","","Yes","","","","","",""
"09/14/2022 at 7:09 pm","Jeff","Guy","Jeffguy@gmail.com","3018441239","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","Kara Guy","Yes","","","","","2","Nadia Guy","","","",""
"09/14/2022 at 7:09 pm","Rebecca ","Guy","rebstill@gmail.com","8048394625","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","Kara Guy","Yes","","","","","2","Nadia Guy","","","",""
"09/14/2022 at 6:53 pm","Mitchell ","Gutshall","Mguts001@verizon.net","2402775384","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Davey Gutshall","No","","","","No","1","Ellie Gutshall","","","",""
"09/14/2022 at 6:53 pm","Marianne ","Gutshall","mgutshall@gmail.com","4434733740","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Davey Gutshall","Yes","","","","Yes","1","Ellie Gutshall","","","",""
"09/14/2022 at 4:26 pm","Talia","Skyles","talia_skyles@hcpss.org","3019221380","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","",""
"09/14/2022 at 11:50 am","Jennifer ","Tinnirella","Jagoodemote@gmail.com","4439040473","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","1","Shaylee Tinnirella","No","","","","","","","","","",""
"09/14/2022 at 11:50 am","Anthony ","Tinnirella","ajtinnirella@gmail.com","4102411388","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","1","Shaylee Tinnirella","No","","","","","","","","","",""
"09/13/2022 at 6:48 pm","Jason","Mabee","Jason.mabee1@gmail.com","443-255-4135","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","1","Grant Mabee","No","","","","","","","","","",""
"09/13/2022 at 6:48 pm","Adrienne","Mabee ","adrienne.mabee@gmail.com","4434528612","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","1","Grant Mabee","Yes","","","","","5","Bryn Mabee","","","",""
"09/13/2022 at 6:45 pm","Nicole","Gable","cmgable37@gmail.com","4436764204","Parent/Guardian","","Store Purchase","2022 - 2023","$75.00","","","","","2","Linzey Gable","No","No","","","","","",""
"09/13/2022 at 6:02 pm","Jennifer","Fitzpatrick","jenfitz1283@gmail.com","4438785344","Parent/Guardian","","Store Purchase","2022 - 2023","$12.00","","","","No","1","Devyn Fitzpatrick ","","","","","","","3","Brooks Fitzpatrick "
"09/13/2022 at 6:01 pm","Abhishek","Rege","abhishekrege@gmail.com","4104998349","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","1","Oorja Rege","Yes","","","","","","","","","",""
"09/13/2022 at 6:01 pm","Avanti","Shetye","avshetye@gmail.com","2405158469","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","1","Oorja Rege","Yes","","","","","","","","","",""
"09/13/2022 at 5:36 pm","Daniel","Ji","Danielaramji@gmail.com","4438126426","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","K","Eli Ji","Yes","","","","No","","","","","",""
"09/13/2022 at 5:36 pm","Deborah","Yi","Deborahmyi@gmail.com","9178818945","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","K","Eli Ji","Yes","","","","Yes","","","","","",""
"09/13/2022 at 12:53 pm","Laura","Rose","laura.eva.rose@gmail.com","3307048863","Parent/Guardian","","Store Purchase","2022 - 2023","$75.00","","","","","K","Maddox Howe","Yes","Yes","","","","","",""
"09/12/2022 at 10:01 pm","Jeanne","DeBoy","jdeboy@hcpss.org","","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","",""
"09/12/2022 at 8:24 pm","Amy","Bailey","amy_bailey@hcpss.org","","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","",""
"09/12/2022 at 8:15 pm","Andrea","Pendergast","andrea_pendergast@hcpss.org","5514863820","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","",""
"09/12/2022 at 8:15 pm","Maddie","McErlean","madeline_mcerlean@hcpss.org","4103369883","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","",""
"09/12/2022 at 6:11 pm","Bill ","Rodney","Brodney@optonline.net","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Samantha Rodney ","No","","","","","","","","","","",""
"09/12/2022 at 6:11 pm","Donna","Rodney","gelchiondm@gmail.com","6318480162","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Samantha Rodney ","Yes","","","","","","","","","","",""
"09/12/2022 at 4:07 pm","Esther","Jean-Louis","esther_jean-louis@hcpss.org","4438327187","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","",""
"09/12/2022 at 4:00 pm","Kyle","Robson","Kar0880@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","1","Paige Robson","Yes","","","","","","","","","","",""
"09/12/2022 at 4:00 pm","Kristina","Robson","kristinanrobson@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","1","Paige Robson","Yes","","","","","","","","","","",""
"09/12/2022 at 1:19 pm","Robert ","Schmidt ","Rob.a.schmidt@gmail.com","301-875-2785","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","2","Ella Schmidt ","Yes","","","","No","","","","","","",""
"09/12/2022 at 1:19 pm","Ashley","Schmidt","ancook85@gmail.com","4105300024","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","2","Ella Schmidt ","Yes","","","","No","","","","","","",""
"09/12/2022 at 1:04 pm","Vinoth kumar ","Mohan kumar","Vinoth.mohank@gmail.com","8607134762","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","2","Aditi Vinod","Yes","","","","","","","","","","",""
"09/12/2022 at 1:04 pm","Parvadha suganya","Manimude","parvadha.suganya@gmail.com","8604715173","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","2","Aditi Vinod","Yes","","","","","","","","","","",""
"09/12/2022 at 11:52 am","Kimberly ","Young","yyoung@bcps.org","","Grandparent","","Store Purchase","2022 - 2023","$15.00","","4","Sky Burris","Yes","","","","","2","Sage Burris","","","","",""
"09/12/2022 at 11:52 am","Yardley","Young","Yardleyyoung@ymail.com","4435400049","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","Sky Burris","Yes","","","","","2","Sage Burris","","","","",""
"09/12/2022 at 10:16 am","Joe","Murray","joseph.c.murray@gmail.com","510-484-1153","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","1","Ethan Murray","No","","","","No","","","","","","",""
"09/12/2022 at 10:16 am","Carrie","Murray","carrie.chao.murray@gmail.com","415-846-9941","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","1","Ethan Murray","Yes","","","","Yes","","","","","","",""
"09/11/2022 at 4:02 pm","Santosh ","Venkatesha","santosh123@gmail.com","443-621-4424","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Akash Venkatesha","Yes","","","","No","","","","","","",""
"09/11/2022 at 4:02 pm","Mona","Gahunia","mkg112@gmail.com","4435406214","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Akash Venkatesha","Yes","","","","Yes","","","","","","",""
"09/10/2022 at 8:45 pm","Brian","Johnson","bjohnson31@gmail.com","4109359136","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Grant Johnson","Yes","","","","","","","","","","",""
"09/10/2022 at 8:45 pm","Elizabeth ","Johnson","eajohnson621@gmail.com","2404223408","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Grant Johnson","Yes","","","","","","","","","","",""
"09/10/2022 at 7:27 pm","Alexander","Livieratos","Aleclivi@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Paxton livieratos","No","","","","Yes","2","Thea livieratos","","","","",""
"09/10/2022 at 7:27 pm","Kelly","Livieratos","kellykm@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Paxton Livieratos","Yes","","","","Yes","2","Thea Livieratos","","","","",""
"09/10/2022 at 4:42 pm","Laurie ","Daman","ljdaman@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","Elena Daman","Yes","","","","","","","","","","",""
"09/10/2022 at 4:42 pm","Kurt","Daman","kdaman77@gmail.com","4436990849","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","Elena Daman","Yes","","","","","","","","","","",""
"09/10/2022 at 2:19 pm","Thomas","Ruo","Rrmedoff@yahoo.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Robert Ruo","No","","","","No","2","Jason Ruo","","","","",""
"09/10/2022 at 2:19 pm","Rachel","Ruo","rrmedoff@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Robert Ruo","No","","","","No","2","Jason Ruo","","","","",""
"09/10/2022 at 1:49 pm","Beverly","Weber","bevy.lynn@gmail.com","","Parent/Guardian","","Cash","2022 - 2023","$30.00","","","","Yes","3","Isaac Weber","","","","","","","5","Anderson Weber",""
"09/10/2022 at 1:47 pm","Akdas","Mumtaz","akdasmumtaz@gmail.com","","Parent/Guardian","","Cash","2022 - 2023","$30.00","","","","Yes","K","Hiba Mumtaz","","","","","","","","",""
"09/10/2022 at 1:29 pm","Tabassum","Sarfraz","Muminah2011@gmail.com","","Parent/Guardian","Square (BTSP)","Check","2022 - 2023","$30.00","","","","Yes","4","Nuraniya Tahir","","","","","","","K","Tasbiha Tahir",""
"09/10/2022 at 1:26 pm","Joohee","Chae","chaejoo84@gmail.com","","Parent/Guardian","Square (BTSP)","Check","2022 - 2023","$12.00","","","","No","4","Subeen Oh","","","","","","","3","Seoyeon Oh",""
"09/10/2022 at 1:23 pm","Jaye","Van Acht","jayevanacht@gmail.com","","Parent/Guardian","Square (BTSP)","Check","2022 - 2023","$75.00","","","","","5","Grey Van Acht","No","Yes","","","","","","Saul Van Acht",""
"09/09/2022 at 6:02 pm","Erin","Coleman","2030erin@gmail.com","4103702508","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","",""
"09/09/2022 at 4:16 pm","Jeff","Plank","jplank3020@gmail.com","4102274952","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","5","Whitney Plank","No","","","","Yes","3","Everett Plank","","","","",""
"09/09/2022 at 4:16 pm","Corinne","Plank","cplank2225@gmail.com","4106529305","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","5","Whitney Plank","Yes","","","","Yes","3","Everett Plank","","","","",""
"09/09/2022 at 4:16 pm","Corinne","Plank","cplank1225@gmail.com","4106529305","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","5","Whitney Plank","Yes","","","","Yes","3","Everett Plank","","","","",""
"09/09/2022 at 4:13 pm","Brad","Piergrossi","Bradpiergrossi@yahoo.com","4109387396","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Fiona Raftery Piergrossi","Yes","","","","No","4","Aleena Raftery Piergrossi","","","","",""
"09/09/2022 at 4:13 pm","Martina","Raftery","tinaraftery@yahoo.com","4438441908","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Fiona Raftery Piergrossi","Yes","","","","No","4","Aleena Raftery Piergrossi","Brad Piergrossi","","","",""
"09/09/2022 at 2:59 pm","Patricia","Lough Buzzerd","Pat.A.Lough@GMAIL.COM","3014520150","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","1","Allison Buzzerd","No","","","","","","","","","","",""
"09/09/2022 at 2:59 pm","Christian","Buzzerd","LOUGHBUZZERD@GMAIL.COM","4432543400","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","1","Allison Buzzerd ","Yes","","","","","","","","","","",""
"09/09/2022 at 8:19 am","kevin","knott","kevin.knott2@gmail.com","","Parent/Guardian","","Cash","2022 - 2023","$5.00","","","","No","4","bryan knott","","","","","","","2","chloe knott",""
"09/09/2022 at 7:38 am","Christina","Harold","christina_harold@hcpss.org","","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","",""
"09/08/2022 at 10:35 pm","Stephen","Senerchia","steve@senerchia.com","","Parent/Guardian","","Cash","2022 - 2023","$37.50","","4","Sofee Senerchia","No","","","","Yes","1","Mia Senerchia","","","","",""
"09/08/2022 at 10:35 pm","Sara","Senerchia","sara@senerchia.com","","Parent/Guardian","","Cash","2022 - 2023","$37.50","","4","Sofee Senerchia","Yes","","","","Yes","1","Mia Senerchia","","","","",""
"09/08/2022 at 4:06 pm","Xin","Li","Lixintt.chn@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","1","Hailey Tao","Yes","","","","Yes","4","Bryan Tao","","","","",""
"09/08/2022 at 4:06 pm","Tao","Tao ","Taotao.chn@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","1","Hailey Tao","Yes","","","","Yes","4","Bryan Tao","","","","",""
"09/08/2022 at 2:17 pm","Eun-Chung","Cintron","eun-chung_cintron@hcpss.org","","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","",""
"09/08/2022 at 10:31 am","Josh","Ferguson","joshuatferguson@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","5","Hailey Ferguson","No","","","","","3","Evan Ferguson","","Alex Ferguson","","","K"
"09/08/2022 at 10:31 am","Linda","Ferguso","linda.f.ferguson@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","5","Hailey Ferguson","Yes","","","","","3","Evan Ferguson","","Alex Ferguson","","","K"
"09/08/2022 at 8:18 am","Kevin ","Sharpe","Ksharpe45@gmail.com","4436236643","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","Kylie Sharpe","No","","","","","","","","","","",""
"09/08/2022 at 8:18 am","Colleen","Cavanaugh ","Csquared27@gmail.com","3152547584","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","Kylie Sharpe","Yes","","","","","","","","","","",""
"09/08/2022 at 6:55 am","Chidimma","Agbakwuru","chidimmaa@gmail.com","","Parent/Guardian","","Cash","2022 - 2023","$37.50","","K","Elaine Agbakwuru","No","","","","Yes","","","","","","",""
"09/08/2022 at 6:55 am","Chinedu","Agbakwuru","edwuru@gmail.com","","Parent/Guardian","","Cash","2022 - 2023","$37.50","","K","Elaine Agbakwuru","No","","","","Yes","","","","","","",""
"09/07/2022 at 10:47 pm","Lily","Park","insuzzang81@hotmail.com","4437149711","Parent/Guardian","","Store Purchase","2022 - 2023","$12.00","","","","Yes","4","Nathaniel Park","","","","","","","","",""
"09/07/2022 at 10:07 pm","Calvin","Ball","cball@howardcountymd.gov","","Community","","Cash","2022 - 2023","$12.00","","","","No","K","N/A","","","","","","","","",""
"09/07/2022 at 9:49 pm","Maryam","Diaz","maryamgdiaz@gmail.com","","Parent/Guardian","","Cash","2022 - 2023","$37.50","","K","Samantha Diaz","Yes","","","","Yes","","","","","","",""
"09/07/2022 at 9:49 pm","Alvin","Diaz","alvin1782@yahoo.com","","Parent/Guardian","","Cash","2022 - 2023","$37.50","","K","Samantha Diaz","Yes","","","","Yes","","","","","","",""
"09/07/2022 at 9:32 pm","Craig","Newcomb","cknewcomb@gmail.com","443-896-4412","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Annelise Newcomb","No","","","","No","2","Lorelei Newcomb","","","","",""
"09/07/2022 at 9:32 pm","Jennifer","Newcomb","jflanigan@gmail.com","717-495-4596","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Annelise Newcomb","Yes","","","","Yes","2","Lorelei Newcomb","","","","",""
"09/07/2022 at 7:41 pm","Frances","Felder","franwfelder@gmail.com","4103400988","Parent/Guardian","","Store Purchase","2022 - 2023","$75.00","","","","","5","Delayni Felder","Yes","Yes","","","","","","",""
"09/07/2022 at 7:11 pm","Nina","Philipsen","nm.philipsen@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$12.00","","","","Yes","5","Nora Hetzner","","","","","","","","",""
"09/07/2022 at 6:47 pm","David","Goggin","Dgoggin77@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","1","Emma Goggin","No","","","","","","","","","","",""
"09/07/2022 at 6:47 pm","Sara","Goggin","sgoggin22@gmail.com","6177557387","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","1","Emma Goggin","Yes","","","","","","","","","","",""
"09/07/2022 at 6:47 pm","Brian ","Day","Briday50@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","1","Ellie Day","No","","","","No","","","","","","",""
"09/07/2022 at 6:47 pm","Sarah ","Day","sarahday52@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","1","Ellie day","Yes","","","","No","","","","","","",""
"09/07/2022 at 6:41 pm","Dan","Notari","dnotari44@gmail.com","4103132813","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","",""
"09/07/2022 at 6:04 pm","Michael","Brewer","michaeldbrewer1974@gmail.com","4107030386","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","Evelyn Brewer","No","","","","","","","","","","",""
"09/07/2022 at 6:04 pm","Katherine","Brewer","katie.cardoni.brewer@gmail.com","7037856121","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","Evelyn Brewer","Yes","","","","","","","","","","",""
"09/07/2022 at 5:54 pm","Seth","Groman","seth.groman@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","3","Max Groman","No","","","","No","","","","","","",""
"09/07/2022 at 5:54 pm","Jenna","Groman","Jenna.groman@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","3","Max Groman","Yes","","","","Yes","","","","","","",""
"09/07/2022 at 5:05 pm","Bob","Bergin","bobbybergin@hotmail.com","","Parent/Guardian","","Cash","2022 - 2023","$37.50","","4","Ruby Bergin","Yes","","","","Yes","3","Grant Bergin","","","","",""
"09/07/2022 at 5:05 pm","Mandy","Bergin","mandybergin@hotmail.com","","Parent/Guardian","230","Check","2022 - 2023","$37.50","","3","Grant Bergin","Yes","","","","Yes","4","Ruby Bergin","","","","",""
"09/07/2022 at 4:58 pm","Kevin","Cooke","kcooke2442@gmail.com","","Parent/Guardian","","Cash","2022 - 2023","$37.50","","K","John Cooke","Yes","","","","Yes","","","","","","",""
"09/07/2022 at 4:58 pm","Sarah ","Cooke","sarahcooke2015@gmail.com","","Parent/Guardian","255","Check","2022 - 2023","$37.50","","K","John Cooke","Yes","","","","Yes","","","","","","",""
"09/07/2022 at 4:42 pm","Kyung","Oh","klee6256@gmail.com","4436904290","Parent/Guardian","","Cash","2022 - 2023","$15.00","","1","Jeremy Oh","No","","","","","","","","","","",""
"09/07/2022 at 4:42 pm","Thomas","Oh","yoojaeha@hotmail.com","","Parent/Guardian","308","Check","2022 - 2023","$15.00","","1","Jeremy Oh","No","","","","","","","","","","",""
"09/07/2022 at 1:45 pm","Lucas","Grace","Lukeandlinds@comcast.net","4437456636","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","1","Kylie Grace","Yes","","","","Yes","K","Mackenzie Grace","","","","",""
"09/07/2022 at 1:45 pm","Lindsay","Grace","lindsaypickett24@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","1","Kylie Grace","Yes","","","","Yes","K","Mackenzie Grace","","","","",""
"09/07/2022 at 11:28 am","ANISH","SHAIKH","anish786@gmail.com","4109055706","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","MohammadAamir Shaikh","Yes","","","","","","","","","","",""
"09/07/2022 at 11:28 am","HINA ","SHAIKH","hina7860@gmail.com","4439850708","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","MohammadAamir Shaikh","Yes","","","","","","","ANISH SHAIKH","","","",""
"09/07/2022 at 9:28 am","Melissa","Orgera","melissa_orgera@hcpss.org","","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","No","","","","","","","","","","",""
"09/06/2022 at 9:14 pm","Michele","Barron","mlbarron10@gmail.com","4109250146","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","",""
"09/06/2022 at 8:14 pm","Tim","Kelley","Tkelley9175@gmail.com","410-925-2283","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","Jack Kelley","No","","","","","","","","","","",""
"09/06/2022 at 8:14 pm","Carrie","Kelley","Ckelley917@yahoo.com","410-206-9490","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","Jack Kelley","No","","","","","","","","","","",""
"09/06/2022 at 5:36 pm","Justin","Ford","22jayferd@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","2","Kathryn Ford","No","","","","","K","Owen Ford","","","","",""
"09/06/2022 at 5:36 pm","Jennifer","Ford","jmpiechocki@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","2","Kathryn Ford","Yes","","","","","K","Owen Ford","","","","",""
"09/06/2022 at 4:18 pm","Jimmy","Brown ","tarheel931@gmail.com","706-267-8547","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Sullivan Brown ","No","","","","","","","","","","",""
"09/06/2022 at 4:18 pm","Mary","Brown ","marbear610@yahoo.com","706-267-9457","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Sullivan Brown ","Yes","","","","","","","","","","",""
"09/06/2022 at 3:46 pm","Sarah","Fauver ","sarah_fauver@hcpss.org","4438124299","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","",""
"09/06/2022 at 1:59 pm","Amy","Leisner","Amy_Leisner@hcpss.org","443-603-4343","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","",""
"09/06/2022 at 1:57 pm","Rob","Davis","robraydavis@gmail.com","2672535568","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Drew Davis","No","","","","","","","","","","",""
"09/06/2022 at 1:57 pm","Amala","Davis","amaladavis75@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Drew Davis","Yes","","","","","","Drew Davis","","","","",""
"09/06/2022 at 1:40 pm","Max ","Fiallos","maxfiallos@gmail.com","4434694191","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Sebastian Fiallos","No","","","","No","3","Natalia Fiallos","","","","",""
"09/06/2022 at 1:40 pm","Telma","Batres","telmabatres@gmail.com","4434227784","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Sebastian Fiallos","Yes","","","","Yes","3","Natalia Fiallos","","","","",""
"09/06/2022 at 12:25 pm","Drew","Petrella","vapetrella@gmail.com","2405053266","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","3","Vance Petrella","No","","","","Yes","","","","","","",""
"09/06/2022 at 12:25 pm","Liz","Petrella","petrella.liz@gmail.com","3015128186","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","3","Vance Petrella","Yes","","","","Yes","","","","","","",""
"09/06/2022 at 12:17 pm","Jessica Roy-Harrison","Roy-Harrison","jroyharrison@gmail.com","4348254611","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Maximus Bridges","Yes","","","","","3","Alora Bridges","","","","",""
"09/06/2022 at 12:17 pm","David","Bridges","dobridges@me.com","4349890736","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","David Bridges","Yes","","","","","3","Maximus Bridges","","Alora Bridges","","",""
"09/05/2022 at 9:44 pm","Shelly","Post","shellylpost@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$12.00","","","","Yes","4","Naomi Post","","","","","","","2","Aila Post",""
"09/05/2022 at 8:17 pm","Kee","Jang","kwjang28@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Nathan Jang","No","","","","","","","","","","",""
"09/05/2022 at 8:17 pm","Kee","Jang","anajang65@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Nathan Jang","Yes","","","","","","","","","","",""
"09/05/2022 at 7:38 am","Preston","Schoenly","lisacass@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","3","Nathan Schoenly","No","","","","No","","Mason Schoenly","","","","",""
"09/05/2022 at 7:38 am","Lisa","Schoenly","lisaschoenly@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","3","Nathan Schoenly","Yes","","","","Yes","1","Mason Schoenly","","","","",""
"09/04/2022 at 8:10 pm","Kevin","Drummond","","4437948245","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","5","Dylan Drummond","No","","","","No","","","","","","",""
"09/04/2022 at 8:10 pm","Kasey","Drummond","kaseydrummond@yahoo.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","5","Dylan Drummond","No","","","","No","","","","","","","","",""
"09/04/2022 at 12:56 pm","Erica","Voss","ericavoss@yahoo.com","410 844 2496","Parent/Guardian","","Store Purchase","2022 - 2023","$12.00","","","Elizabeth Cherry ","Yes","","","","","","","","","","","","K",""
"09/04/2022 at 12:03 pm","Scott","Hays ","Sahays12@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","Hailey ","No","","","","","","","","","","","","",""
"09/04/2022 at 12:03 pm","Miriam","Hays","mmhays9@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","Hailey Hays ","No","","","","","2","Payton Hays","","","","","","",""
"09/04/2022 at 11:36 am","Chris","Rosas","Christopher_rosas@hcpss.org","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","5","Nicki Rosas","No","","","","","","","","","","","","",""
"09/04/2022 at 11:36 am","Beth","Rosas","Beth_Rosas@hcpss.org","3017689171","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","5","Nicki Rosas","Yes","","","","","","","","","","","","",""
"09/03/2022 at 9:46 pm","Christa ","Marsico","christa_marsico@hcpss.org","4432859415","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","","","",""
"09/03/2022 at 9:20 pm","Kevin ","Rodkey","Kevin.rodkey@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","1","Grace Rodkey ","No","","","","","","","","","","","","",""
"09/03/2022 at 9:20 pm","Erika","Rodkey","erika.rodkey@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","1","Grace Rodkey ","Yes","","","","","","","","","","","","",""
"09/03/2022 at 12:17 pm","Bhavik ","Hukmani","b2hukmani@yahoo.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","Damian Hukmani","No","","","","","","","","","","","","",""
"09/03/2022 at 12:17 pm","Kelly","Hukmani","kehukmani@yahoo.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","Damian Hukmani","No","","","","","","","","","","","","",""
"09/03/2022 at 12:10 pm","Gary","Smith","gsmith072608@gmail.com","4104598056","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","2","Oscar Smith","No","","","","Yes","K","Laura Smith","","","","","","",""
"09/03/2022 at 12:10 pm","Sadie","Smith","smatarazzosmith@gmail.com","4109168430","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","2","Oscar Smith","Yes","","","","Yes","K","Laura Smith","","","","","","",""
"09/03/2022 at 11:38 am","Michael ","Moskowitz ","mjmoskowitz@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","Anya Moskowitz ","No","","","","","","","","","","","","",""
"09/03/2022 at 11:38 am","Sayli","Moskowitz","sayliw@gmail.com","2024863103","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","Anya Moskowitz","Yes","","","","","","","","","","","","",""
"09/03/2022 at 9:19 am","Jennifer","Olchowski","jenniferparandian@yahoo.com","4435403138","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Charlotte Olchowski","Yes","","","","","","","","","","","","",""
"09/03/2022 at 9:19 am","Adam","Olchowski ","olchowskia@yahoo.com","4103823364","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Charlotte Olchowski","No","","","","","","","Jennifer Olchowski","","","","","",""
"09/03/2022 at 9:12 am","Roxi","Da Silva","Roxitoo@gmail.com","443-799-9551","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","K","Giovanni Da Silva","Yes","","","","","","","","","","","","",""
"09/03/2022 at 9:12 am","Diego","Da Silva","Sumoamor@gmail.com","410-204-2880","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","K","Giovanni Da Silva","Yes","","","","","","","","","","","","",""
"09/03/2022 at 8:56 am","Michael ","McCormick","mmccor12@gmail.com","4109677949","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","1","Liana McCormick ","No","","","","Yes","","","","","","","","",""
"09/03/2022 at 8:56 am","Heather","McCormick","hurdheather87@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","1","Liana McCormick","Yes","","","","Yes","","","Mike McCormick","","","","","",""
"09/02/2022 at 10:07 pm","Richard ","Cresswell","rcresswell@gmail.com","443-621-3307","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","5","Logan Cresswell","No","","","","No","3","Kalina Cresswell","","","","","","",""
"09/02/2022 at 10:07 pm","Kasandra","Cresswell","kasandracresswell@gmail.com","301-502-7037","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","5","Logan Cresswell","No","","","","Yes","3","Kalina Cresswell","","","","","","",""
"09/02/2022 at 4:20 pm","Glenn","Wolfe","zlonewolfe@gmail.com","2069204947","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","3","Ethan Wolfe","No","","","","No","K","Jackson Wolfe","","","","","","",""
"09/02/2022 at 4:20 pm","Jamie","Wolfe","rainyjamie8@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","3","Ethan Wolfe","Yes","","","","Yes","K","Jackson Wolfe","Jamie Wolfe","","","","","",""
"09/02/2022 at 3:14 pm","Maryiam","Cutlerywala","busybeeqk786@yahoo.com","443-670-6555","Faculty/Staff","","Cash","2022 - 2023","$10.00","","","","","","","","","","","","","","","","",""
"09/02/2022 at 10:50 am","Alan","Kramer","ackramer@hotmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","5","Calista Kramer","No","","","","","","","","","","","","",""
"09/02/2022 at 10:50 am","Angie","Kramer","angela.l.kramer@gmail.com","4108186622","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","5","Calista Kramer","Yes","","","","","","","","","","","","",""
"09/02/2022 at 7:43 am","Mark","Den Herder","Mdherder000@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","5","Emmma Den Herder","No","","","","","","","","","","","","",""
"09/02/2022 at 7:43 am","Christine","Den Herder","Cdenherder@gmail.com","613-967-3159","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","5","Emma Den Herder ","Yes","","","","","","","","","","","","",""
"09/01/2022 at 9:28 pm","Adam ","Fisher","adam.fisher.personal@gmail.com","4436778847","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","5","Ruby Fisher","No","","","","No","3","Gary Fisher","","","","","","",""
"09/01/2022 at 9:28 pm","Jane","Fisher","jane.gribble@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","5","Ruby Fisher","No","","","","No","3","Gary Fisher","Jane R Fisher","","","","","",""
"09/01/2022 at 9:22 pm","Christian","Vainieri","Vainiericm@gmail.com","9179231531","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","5","Milo Vainieri","Yes","","","","No","5","Emmett Vainierj","","","","","","",""
"09/01/2022 at 9:22 pm","EMILY","VAINIERI","thepiendak@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","5","Milo Vainieri","Yes","","","","Yes","5","Emmett Vainieri","","","","","","",""
"09/01/2022 at 9:22 pm","EMILY","VAINIERI","emily.vainieri1@maryland.gov","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","5","Milo Vainieri","Yes","","","","Yes","5","Emmett Vainieri","","","","","","",""
"09/01/2022 at 7:53 pm","Harris","Gofstein","Hascogo@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Juliet Gofstein ","No","","","","No","","","","","","","","",""
"09/01/2022 at 7:53 pm","Danielle","Gofstein","danielle.steiner@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Juliet Gofstein","Yes","","","","Yes","","","","","","","","",""
"09/01/2022 at 6:31 pm","Rachel ","Haak","ocjetskimom@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$12.00","","","Rose Haak ","Yes","","","","","","","","","","","","5",""
"09/01/2022 at 4:02 pm","Brittany","Gutierrez","brittanyegutierrez@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$12.00","","","Andres Gutierrez ","Yes","","","","","","Marcelo Gutierrez ","","","","","","3","1"
"09/01/2022 at 4:02 pm","Eric","Nolan","nolanericj@gmail.com","2543835516","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","1","Jacob Nolan ","No","","","","","","","","","","","","",""
"09/01/2022 at 4:02 pm","Dana","Nolan","Dana.s.nolan@gmail.com","9089024102","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","1","Jacob Nolan","Yes","","","","","","","","","","","","",""
"09/01/2022 at 2:44 pm","Jackie","DeBella ","jacquelyn_debella@hcpss.org","4103135000","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","","","",""
"09/01/2022 at 2:41 pm","Amanda","Diaz","Amanda_diaz@hcpss.org","4107074576","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","","","",""
"08/31/2022 at 8:21 pm","Chad","Van Patten","cvanpatten@sumologic.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","K","Eli Van Patten","No","","","","No","3","Isaac Van Patten","","","","","","",""
"08/31/2022 at 8:21 pm","Elizabeth","Van Patten","elizabethvanpatten@gmail.com","4436522861","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","K","Eli Van Patten","Yes","","","","Yes","3","Isaac Van Patten","Chad Van Patten","","","","","",""
"08/31/2022 at 4:43 pm","Patrick","Devine","m9adevip@yahoo.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Parker","No","","","","No","K","Savannah","","","","","","",""
"08/31/2022 at 4:43 pm","Jennifer","Devine","jlmgls@gmail.com","4437451851","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Parker Devine","Yes","","","","Yes","K","Savannah Devine","Patrick d Devine","","","","","",""
"08/31/2022 at 2:13 pm","JeeMin","Lee","jeemin_lee@hcpss.org","","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","","","",""
"08/31/2022 at 1:13 pm","Sharon ","Nath","sbn5160@gmail.com","4432543389","Parent/Guardian","","Store Purchase","2022 - 2023","$12.00","","","Brayden Nath","Yes","","","","","","","","","","","","4",""
"08/31/2022 at 12:42 pm","Thomas ","Noble","thomas.m.noble@gmail.com","410-205-9170","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Joseph Noble","No","","","","","1","Tucker Noble","","","","","","",""
"08/31/2022 at 12:42 pm","Leela","Noble","lcollins802@gmail.com","4434650837","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Joseph Noble","Yes","","","","","1","Tucker Noble","Leela Noble","","","","","",""
"08/31/2022 at 11:49 am","Reddy N","Apoori","anr747@yahoo.com","5712750943","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","Aditya Apoori","No","","","","","","","","","","","","","","","",""
"08/31/2022 at 11:49 am","Latha","Ramachandran","latha2310@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","4","Aditya Apoori","No","","","","","","","","","","","","","","","",""
"08/31/2022 at 11:14 am","Erin","Fowler","Erin_n_fowler@hcpss.org","","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","","","","","","",""
"08/31/2022 at 10:55 am","Matthew ","Maschal","mmdrummerjpc@yahoo.com","4435276276","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","2","Chelsea Harumi Maschal","Yes","","","","Yes","","","","","","","","","","","",""
"08/31/2022 at 10:55 am","Sayuri ","Kamimura ","sayurikamimura@hotmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","2","Chelsea Harumi Maschal","Yes","","","","Yes","","","matthew r maschal","","","","","","","","",""
"08/31/2022 at 10:42 am","David","Kane","Dkane417@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","2","Mollie Kane","Yes","","","","Yes","K","Isla Kane","","","","","","","","","",""
"08/31/2022 at 10:42 am","Christina","Kane","Christinam.kane@gmail.com","4436671518","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","2","Mollie Kane","Yes","","","","Yes","K","Isla Kane","","","","","","","","","",""
"08/31/2022 at 9:31 am","Michael","Eitelman","eitelmanm@gmail.com","9105839045","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Aaron Mason","No","","","","","3","Gabriel Eitelman","","Sean Eitelman","","","5","","","","",""
"08/31/2022 at 9:31 am","Megan","Mason","meganmason1@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Aaron Mason","Yes","","","","","3","Gabriel Eitelman","","Sean Eitelman","","","5","","","","",""
"08/31/2022 at 9:23 am","Becky","Poirier","rebecca_poirier@hcpss.org","","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","","","","","","",""
"08/31/2022 at 7:33 am","Kelli","Byle","kbyle@hcpss.org","","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","","","","","","",""
"08/30/2022 at 9:31 pm","Natalie","Blake","Natalie_Blake@hcpss.org","2402155990","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","","","","","","",""
"08/30/2022 at 6:32 pm","Keegan","Tozaki","keegantozaki@me.com","3016765330","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Vera Nieto","Yes","","","","No","","","","","","","","","","","",""
"08/30/2022 at 6:32 pm","Jaclyn ","Tozaki ","avmomrn@gmail.com","2026791758","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","4","Vera Nieto","Yes","","","","No","","","","","","","","","","","",""
"08/30/2022 at 4:37 pm","Vanessa","Lichliter","vanessa_lichliter@hcpss.org","4438647995","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","","","","","","",""
"08/30/2022 at 3:37 pm","Kelly","Pavlic","Kelly_pavlic@hcpss.org","7246009240","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","","","","","","",""
"08/30/2022 at 3:17 pm","Kelly","Rippeon","kelly_rippeon@hcpss.org","","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","","","","","","",""
"08/30/2022 at 2:41 pm","Elizabeth","Taylor","elizabeth_taylor@hcpss.org","","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","","","","","","",""
"08/30/2022 at 1:14 pm","Pieter","Baker","pieter.baker@gmail.com","7606705130","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","K","Juliette Baker","No","","","","","2","Max Baker","","","","","","","","","",""
"08/30/2022 at 1:14 pm","Monica","Baker","monicarosebaker@gmail.com","7605226514","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","K","Juliette Baker","Yes","","","","","2","Max Baker","Pieter Baker","","","","","","","","",""
"08/28/2022 at 7:13 pm","Paul","Halvorsen","paul@halvo.me","","Parent/Guardian","","Cash","2022 - 2023","$37.50","","1","David Halvorsen","Yes","","","","No","3","Lily Halvorsen","","","","","","","","","",""
"08/28/2022 at 7:13 pm","Meg","Halvorsen","meg.halvorsen@gmail.com","","Parent/Guardian","","Cash","2022 - 2023","$37.50","","1","David Halvorsen","Yes","","","","No","3","Lily Halvorsen","","","","","","","","","",""
"08/28/2022 at 2:55 pm","Katrina ","Vala","campingcelebration2014@gmail.com","3522624032","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","K","Amelia Vala","Yes","","","","Yes","","","","","","","","","","","",""
"08/28/2022 at 2:55 pm","Katrina","Vala","katrina.hein@gmail.com","717 315 8296","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","K","Amelia Vala","Yes","","","","Yes","","","","","","","","","","","",""
"08/28/2022 at 2:10 pm","Alan","Mejibovsky ","Mejick24@gmail.com","585-313-1847","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","K","Keegan Mejibovsky ","Yes","","","","","","","","","","","","","","","",""
"08/28/2022 at 2:10 pm","Rachel ","Mejibovsky ","Stamanr1@gmail.com","319-521-6890","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","K","Keegan Mejibovsky ","Yes","","","","","","","","","","","","","","","",""
"08/28/2022 at 9:47 am","Scott","Lambert","slambert815@gmail.com","518-524-0007","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","1","Ella Rachel Lambert","No","","","","","","","","","","","","","","","",""
"08/28/2022 at 9:47 am","Alyssa","Lambert","alyssa.litman@gmail.com","215-833-8085","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","1","Ella Rachel Lambert","Yes","","","","","","","","","","","","","","","",""
"08/26/2022 at 9:40 pm","Brandon","Lawton","lawton.brandon@gmail.com","4436830446","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Mae Lawton","Yes","","","","","","","","","","","","","","","",""
"08/26/2022 at 9:40 pm","Pey Lian","Lim","p3y1i4n@gmail.com","4436830577","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","3","Mae Lawton","Yes","","","","","","","","","","","","","","","",""
"08/26/2022 at 9:25 am","Rebecca","Care","rebecca_care@hcpss.org","4109788063","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","","","","","","",""
"08/26/2022 at 7:10 am","Christina","Harkness","christina_harkness@hcpss.org","4439203138","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","","","","","","",""
"08/25/2022 at 10:19 pm","John","Ballman","xjohnballx@yahoo.com","7142251447","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","3","John Ballman","Yes","","","","No","","","","","","","","","","","",""
"08/25/2022 at 10:19 pm","Megan","Ballman","meg.ballman@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","3","John Ballman","Yes","","","","No","","","","","","","","","","","",""
"08/25/2022 at 9:54 pm","Kevin","Foster","kevin.h.foster@gmail.com","8609174683","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","K","Ashton Foster","Yes","","","","No","","","","","","","","","","","",""
"08/25/2022 at 9:54 pm","Rebecca","Foster","becca.l.foster@gmail.com","6033054221","Faculty/Staff","","Store Purchase","2022 - 2023","$37.50","","K","Ashton Foster","Yes","","","","Yes","","","","","","","","","","","",""
"08/25/2022 at 9:32 pm","Brian","Scully","bjscully4@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","5","Donovan Scully","Yes","","","","Yes","2","Mairead Scully","","","","","","","","","",""
"08/25/2022 at 9:32 pm","Tara","Scully","taramscully@gmail.com","3012214171","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","5","Donovan Scully","Yes","","","","Yes","2","Mairead Scully","","","","","","","","","",""
"08/25/2022 at 9:32 pm","Glenn","Van Scyoc","gevanscyoc@yahoo.com","4104932399","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","K","Sophia Braunstein","Yes","","","","Yes","","","","","","","","","","","",""
"08/25/2022 at 9:32 pm","Kerstin","Braunstein","kerstin.braunstein@gmail.com","4439098503","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","K","Sophia Braunstein","Yes","","","","Yes","","","","","","","","","","","",""
"08/25/2022 at 7:27 pm","Josh","Burns","burnsie42@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","3","Taylor Burns","No","","","","No","1","Jackson Burns","","","","","","","","","Burns","Taylor"
"08/25/2022 at 7:27 pm","Tiffany","Burns","tmb926@yahoo.com","2406456887","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","3","Taylor Burns","No","","","","Yes","1","Jackson Burns","","","","","","","","","Burns","Taylor"
"08/25/2022 at 12:42 pm","Katelyn","Niu","katelyn.y.niu@gmail.com","4109164158","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","K","Alexander Yang","Yes","","","","Yes","","","","","","","","","","","",""
"08/25/2022 at 12:42 pm","Kevin","Yang","kevin.r.yang@gmail.com","4107363596","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","K","Alexander Yang","Yes","","","","Yes","","","","","","","","","","","",""
"08/25/2022 at 9:45 am","Chad","Morris","Morris1175@gmail.com","4108046385","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","K","Nora Morris","Yes","","","","","","","","","","","","","","Beckykaymorris@gmail.com","Morris","Becky"
"08/25/2022 at 9:45 am","Rebecca","Morris","beckykaymorris@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","K","Nora Morris","Yes","","","","","","","","","","","","","","Morris1175@gmail.com","Morris","Chad"
"08/25/2022 at 9:44 am","Mike","Elwell","mrmikeelwell@gmail.com","4109523585","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","K","Waverly Elwell","Yes","","","","Yes","","","","","","","","","","","",""
"08/25/2022 at 9:44 am","Sarah","Elwell","sarahkelwell0927@gmail.com","4102068615","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","K","Waverly Elwell","Yes","","","","Yes","","","","","","","","","","","",""
"08/24/2022 at 6:42 pm","Shira","Levy","ryanmlevy@gmail.com","4104935320","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","2","Maxwell Levy","Yes","","","","","K","Miles Levy","","","","","","","","","",""
"08/24/2022 at 6:42 pm","Shira","Levy","shirarlevy@gmail.com","4437425566","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","2","Maxwell Levy","Yes","","","","","K","Miles Levy","","","","","","","","ryanmlevy@gmail.com","Levy","Ryan"
"08/24/2022 at 6:41 pm","Michael","Bennett","Bennettmichael3@gmail.com","4438120216","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","K","Reese Bennett","Yes","","","","","3","Chase Bennett","","","","","","","","bennettmichael3@gmail.com","Bennett","Michael"
"08/24/2022 at 6:41 pm","Meghan","Bennett","barrmn@yahoo.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","K","Reese Bennett","Yes","","","","","3","Chase Bennett","","","","","","","","barrmn@yahoo.com","Bennett","Meghan"
"08/24/2022 at 2:46 pm","Eric","Wood","clemsoncrab@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","K","Spencer Wood","No","","","","Yes","","","","","","","","","","","",""
"08/24/2022 at 2:46 pm","Kim","Wood","kimberlymariewood@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","K","Spencer Wood","Yes","","","","Yes","","","","","","","","","","","",""
"08/24/2022 at 6:43 am","Tolly","Peddicord","tolly_peddicord@hcpss.org","410-591-9507","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","","","","","","",""
"08/24/2022 at 5:42 am","Kathleen","Griffith","Kathleen_griffith@hcpss.org","4102074776","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","","","","","","",""
"08/22/2022 at 12:17 pm","Cindy","Chen","qixin_chen@hcpss.org","4438519277","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","","","","","","",""
"08/21/2022 at 2:12 pm","John","Hopkins","Jfhopkins01@hotmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","3","Benjamin Hopkins ","No","","","","Yes","","","","","","","","","","","",""
"08/21/2022 at 2:12 pm","Jennifer","Hopkins","Piccolag8r@hotmail.com","3212460421","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","3","Benjamin Hopkins","Yes","","","","Yes","","","","","","","","","","Jfhopkins01@hotmail.com","Hopkins","John"
"08/18/2022 at 1:24 am","Chris","Miles","cmiles4@aol.com","","Parent/Guardian","","Cash","2022 - 2023","$5.00","","","","No","","","","","","","","","","","","","","","",""
"08/18/2022 at 1:22 am","Justin","Callaway","justin.c.callaway@gmail.com","","Parent/Guardian","","Cash","2022 - 2023","$5.00","","","","No","","","","","","","","","","","","","","","",""
"08/18/2022 at 1:21 am","Doug","Cherneski","doug.cherneski@gmail.com","","Parent/Guardian","","Cash","2022 - 2023","$5.00","","","","No","","","","","","","","","","","","","","","",""
"08/17/2022 at 7:58 pm","Margaret","Fischer","margaret_fischer@hcpss.org","410-313-2813","Faculty/Staff","","Store Purchase","2022 - 2023","$10.00","","","","","","","","","","","","","","","","","","","",""
"08/17/2022 at 4:48 pm","Michael","O'Neill","mponeill84@gmail.com","4103024802","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","K","Maxwell O'Neill","Yes","","","","Yes","","","","","","","","","","","",""
"08/17/2022 at 4:48 pm","Katherine","O'Neill","karaoneill523@gmail.com","4102180624","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","K","Maxwell O'Neill","Yes","","","","Yes","","","","","","","","","","","",""
"08/17/2022 at 2:55 pm","Harish","Krishnaswamy","harish.swamy@gmail.com","6092731776","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","K","Arvin Krishnaswamy","Yes","","","","Yes","","","","","","","","","","","",""
"08/17/2022 at 2:55 pm","Ashwini","Anjanappa","ashwini.a@gmail.com","4102076273","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","K","Arvin Krishnaswamy","Yes","","","","Yes","","","","","","","","","","","",""
"08/17/2022 at 10:18 am","Jordan ","Wilson","JordanWilson14@gmail.com","240-460-8531","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","2","Ava Wilson","No","","","","","","","","","","","","","","","",""
"08/17/2022 at 10:18 am","Tara","Wilson","TaraWilson0212@gmail.com","410-245-7398","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","2","Ava Wilson","Yes","","","","","","","","","","","","","","JordanWilson14@gmail.com","Wilson","Jordan "
"08/15/2022 at 10:04 am","Elton","Edinborough","eltonseba2014@gmail.com","301-873-8022","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","K","Mena Kurian Edinborough","Yes","","","","Yes","","","","","","","","","","","",""
"08/15/2022 at 10:04 am","Seba","Kurian","seba.kurian@gmail.com","832-603-0301","Parent/Guardian","","Store Purchase","2022 - 2023","$37.50","","K","Mena Kurian Edinborough","Yes","","","","Yes","","","","","","","","","","","",""
"08/14/2022 at 6:44 pm","Steve","Sansone","Sansone50@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","1","Samantha Sansone","No","","","","","","","","","","","","","","","",""
"08/14/2022 at 6:44 pm","Lauren","Sansone","Lauren.c.sansone@gmail.com","4433264535","Parent/Guardian","","Store Purchase","2022 - 2023","$15.00","","1","Samantha Sansone ","Yes","","","","","","","","","","","","","","Sansone50@gmail.com","Sansone","Steve "
"08/10/2022 at 9:07 am","Holly","Miles","hollymiles8@gmail.com","","Faculty/Staff","","Cash","2022 - 2023","$75.00","","1","Kinslie Miles","","","","","","","","","","","","","","","cmiles4@aol.com","Miles","Chris"
"08/09/2022 at 11:55 am","Ashley","Callaway","ashley.e.simmons@gmail.com","410-707-8177","Parent/Guardian","","Store Purchase","2022 - 2023","$30.00","","1","Colin Callaway","Yes","","","","","","","","","","","","","","justin.c.callaway@gmail.com","Callaway","Justin"
"08/08/2022 at 1:46 pm","Candace","Knott","candace.knott@gmail.com","","Parent/Guardian","","Store Purchase","2022 - 2023","$30.00","","4","Bryan Knott","Yes","","","","","2","Chloe Knott","","","","","","","","kevin.knott2@gmail.com","Knott","Kevin"
"07/21/2022 at 9:33 am","Remya","Arul","remyaarul1@gmail.com","7576604855","Parent/Guardian","","Store Purchase","2022 - 2023","$30.00","","K","Kala Cherneski","Yes","","","","","","","","","","","","","","doug.cherneski@gmail.com","Cherneski","Doug"
1 Joined At First Name Last Name Email Mobile Member Type Check Number Type Year Price Paid Status student_1_grade student_1_full_name Would you like to be added to a no-obligation volunteer email list? Student 1 Grade Student 1 Full Name Would you like to be added to a no-obligation volunteer list? Would you like a car magnet as a thank you for your generous donation? student_2_grade student_2_full_name student_4_full_name student_3_full_name Student 2 Grade Student 2 Full Name student_3_grade student_1_grade_level student_2_grade_level Member_2_-_Email Member_2_-_Last name Member_2_-_First name
2 02/07/2023 at 4:53 pm Alexandria Capecci alexandria_capecci@hcpss.org Faculty/Staff Store Purchase 2022 - 2023 $10.00
3 01/25/2023 at 3:48 pm Pamela Buzzerd pamelabuzzerd@gmail.com 3014664634 Grandparent Store Purchase 2022 - 2023 $10.00 1 Allison Buzzerd Yes
4 12/29/2022 at 5:04 pm Anthony Kattukaran anthonykattukaran@yahoo.com 6086283259 Parent/Guardian Store Purchase 2022 - 2023 $75.00 4 George Kattukaran No Yes
5 12/14/2022 at 9:06 pm Phaedra Larner Plarner@hcpss.org 4109487215 Faculty/Staff Store Purchase 2022 - 2023 $12.00 Yes 1 Phaedra Larner
6 11/21/2022 at 1:17 pm Jennifer Lowney jennifer_lowney@hcpss.org 4104043012 Faculty/Staff Store Purchase 2022 - 2023 $10.00
7 11/16/2022 at 8:05 pm Cith Nadarajah Cithparan@gmail.com 4109257631 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Abira Nadarajah Yes 2 Aashna Nadarajah
8 11/16/2022 at 8:05 pm Sudha Nadarajah ss849319@gmail.com 443-841-9319 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Abira Nadarajah Yes 2 Aashna Nadarajah
9 11/09/2022 at 8:59 am Jane Derro Jderro@hcpss.org 443 535 3179 Faculty/Staff Store Purchase 2022 - 2023 $10.00
10 11/03/2022 at 4:13 pm Phaedra Larner Plarner@hotmail.com 410-948-7215 Faculty/Staff Store Purchase 2022 - 2023 $10.00
11 10/26/2022 at 8:13 am Lina Chauhan-Klein lina_chauhan-klein1@hcpss.org 2406547886 Faculty/Staff Store Purchase 2022 - 2023 $10.00
12 10/21/2022 at 9:38 pm Caroline Chisholm carolinewchisholm@gmail.com Parent/Guardian Cash 2022 - 2023 $30.00 Yes 1 Connor Chisholm
13 10/21/2022 at 9:33 pm Kathleen Newberry kathleen_newberry@hcpss.org Faculty/Staff Cash 2022 - 2023 $10.00
14 10/21/2022 at 9:32 pm Jen Alexander jennifer_alexander1@hcpss.org Faculty/Staff Cash 2022 - 2023 $10.00
15 10/21/2022 at 11:33 am Elizabeth Shoff E.ULBRECHT@GMAIL.COM 8147777444 Faculty/Staff Store Purchase 2022 - 2023 $10.00
16 10/20/2022 at 9:03 am Carl Frantz carl_frantz@hcpss.org 2405060888 Faculty/Staff Store Purchase 2022 - 2023 $10.00
17 10/20/2022 at 9:01 am Elizabeth Carty Elizabeth_carty@hcpss.org 2402103520 Faculty/Staff Store Purchase 2022 - 2023 $10.00
18 10/19/2022 at 2:58 pm Rebecca Whitaker Rebecca_Whitaker@hcpss.org Faculty/Staff Store Purchase 2022 - 2023 $10.00
19 10/18/2022 at 4:09 pm Nancy Carter nancy_carter@hcpss.org Faculty/Staff Store Purchase 2022 - 2023 $10.00
20 10/12/2022 at 4:32 pm Katherine Etheridge i8that2@gmail.com 4107502168 Parent/Guardian Store Purchase 2022 - 2023 $75.00 4 Arianna Delaney Yes No
21 10/12/2022 at 1:13 pm Jimmy Kwak Kwak.james@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 1 Henry Kwak No No
22 10/12/2022 at 1:13 pm Jennifer Kwak jennifer.y.kwak@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 1 Henry Kwak Yes No
23 10/12/2022 at 8:58 am Scott Moore Roastedsmoores@gmail.com 3013468777 Parent/Guardian Store Purchase 2022 - 2023 $37.50 2 Filomena Moore No No
24 10/12/2022 at 8:58 am Lara Moore lara.paolini@gmail.com 3013468777 Parent/Guardian Store Purchase 2022 - 2023 $37.50 2 Filomena Moore No No 5 Desmond Moore
25 10/08/2022 at 3:21 pm Peggy Fredriksson Margaret_fredriksson@hcpss.org Faculty/Staff Store Purchase 2022 - 2023 $10.00
26 10/05/2022 at 12:39 pm Alexis Kalivretenos alexis_kalivretenos@hcpss.org 443-765-0907 Faculty/Staff Store Purchase 2022 - 2023 $10.00
27 10/04/2022 at 9:57 pm Jean Austin jean_austin@hcpss.org Faculty/Staff Cash 2022 - 2023 $10.00
28 10/04/2022 at 3:03 pm Chelsea Berube chelsea_berube@hcpss.org Faculty/Staff Store Purchase 2022 - 2023 $10.00
29 10/02/2022 at 9:30 pm Chunling Zhao Chunlingzhao@hotmail.com 2406201699 Parent/Guardian Store Purchase 2022 - 2023 $37.50 1 Nathan Lu Yes Yes 5 Andy Lu
30 10/02/2022 at 9:30 pm Qijin Lu qijinlu@yahoo.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 1 Nathan Lu Yes Yes Andy Lu Chunking Zhao
31 10/01/2022 at 3:34 pm Derek Easter deaste1@hotmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 3 Mabel Easter No No 1 James Easter
32 10/01/2022 at 3:34 pm Carissa Easter carissaeaster@gmail.com 4439043176 Parent/Guardian Store Purchase 2022 - 2023 $37.50 3 Mabel Easter Yes No 1 James Easter
33 09/30/2022 at 8:53 am Jason Drenner drennerjason@gmail.com 3018754226 Parent/Guardian Store Purchase 2022 - 2023 $37.50 1 Rhyze Drenner Yes No 3 Joules Drenner
34 09/30/2022 at 8:53 am Amber Drenner amber.drenner@uwcm.org 4107037019 Parent/Guardian Store Purchase 2022 - 2023 $37.50 1 Amber M Drenner Yes No 3 Rhyze Anjuli Drenner Jason Drenner Joules Epifania Drenner
35 09/27/2022 at 9:49 am Andrew Dain Andyd1@gmail.com 4102411005 Parent/Guardian Store Purchase 2022 - 2023 $37.50 3 Eli Dain Yes No
36 09/27/2022 at 9:49 am Renee Dain renee.dain@gmail.com 4102078276 Parent/Guardian Store Purchase 2022 - 2023 $37.50 3 Eli Dain Yes Yes
37 09/26/2022 at 10:22 pm Kim Cofsky kimberlycofsky@gmail.com Parent/Guardian Cash 2022 - 2023 $30.00 Yes 1 Nora Cofsky
38 09/26/2022 at 10:20 pm Asra Khatoon asramajid1710@gmail.com Parent/Guardian Cash 2022 - 2023 $12.00 Yes 2 Yousuf Majid 1 Zoya Majid
39 09/23/2022 at 3:57 pm Robert Holsopple 4108492914 Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Henry Holsopple Yes Yes
40 09/23/2022 at 3:57 pm Carrie Baran baran.holsopple@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Henry Holsopple Yes Yes
41 09/22/2022 at 12:32 pm Shannon Kennedy Shannon_kennedy@hcpss.org 4107074913 Faculty/Staff Store Purchase 2022 - 2023 $10.00
42 09/21/2022 at 2:37 pm Jack Morton jmorton96@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Anna Morton No
43 09/21/2022 at 2:37 pm Tiffany Preddy tgpreddy@yahoo.com 5122936323 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Anna Morton Yes
44 09/21/2022 at 11:20 am Elizabeth Stern lizandscottwed2013@gmail.com 6174135512 Parent/Guardian Store Purchase 2022 - 2023 $12.00 Yes 2 Andrew Stern 2 Gabriel Stern
45 09/20/2022 at 8:41 pm Swetha Enaganti swethae@gmail.com Parent/Guardian Cash 2022 - 2023 $12.00 Yes 5 Adhvaita Chandar 1 Eshwar Chandar
46 09/19/2022 at 1:47 pm Diana Zhuravel dina.zhuravel@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $12.00 Yes 3 Joshua Zhuravel
47 09/18/2022 at 8:22 pm Ken Ng kennethngdo@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Nora Ng No No
48 09/18/2022 at 8:22 pm Elizabeth Taylor elizabeth.taylor16@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Nora Ng Yes No
49 09/17/2022 at 9:07 pm Michael Mayfield mmfield@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Nolan Mayfield No No 1 Blythe Mayfield
50 09/17/2022 at 9:07 pm Catherine Mayfield cate.mayfield@gmail.com 4153062125 Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Nolan Mayfield No No 1 Blythe Mayfield
51 09/17/2022 at 4:37 pm Michelle Stein michelle.l.stein@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $12.00 Yes 4 Farrah Stein
52 09/16/2022 at 4:35 pm Daniel Becker danielvarebecker@yahoo.com 301-455-9656 Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 Andrew Becker No 1 Bryce Becker
53 09/16/2022 at 4:35 pm Natasha Becker nrbecker08@gmail.com 4104048436 Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 Andrew Becker Yes 1 Bryce Becker
54 09/16/2022 at 8:53 am Tim Lane lane.tim2@gmail.com 4104094617 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Patrick Lane Yes 1 Jack Lane
55 09/16/2022 at 8:53 am Michelle Lane michellelane713@gmail.com 6095757873 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Patrick Lane Yes 1 Jack Lane
56 09/16/2022 at 7:27 am Mike DeSimone Mike.DeSimone@gmail.com Parent/Guardian Cash 2022 - 2023 $50.00 5 Nathan DeSimone Yes No
57 09/16/2022 at 7:27 am Veronica DeSimone VLDeSimone@gmail.com Parent/Guardian 487 Check 2022 - 2023 $50.00 5 Nathan DeSimone Yes No
58 09/15/2022 at 9:57 pm Cindy Mei-Yip cindy.x.mei@gmail.com Parent/Guardian 128 Check 2022 - 2023 $75.00 2 Sara Mei Yip No Yes 5 Summer Mei Yip
59 09/15/2022 at 9:55 pm Wajeeha Qayyumi wajeehas198@gmail.com Parent/Guardian Cash 2022 - 2023 $15.00 3 Zakariya Shahid No 1 Moeez Shahid
60 09/15/2022 at 9:55 pm Shahid Khursheed lovebird4u_usa@yahoo.com Parent/Guardian Cash 2022 - 2023 $15.00 3 Zakariya Shahid No 1 Moeez Shahid
61 09/15/2022 at 7:49 pm Joseph Danquah jbdan72@hotmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 5 Rhema Danquah Yes
62 09/15/2022 at 7:49 pm Mame Danquah mame700@yahoo.com 4104023206 Parent/Guardian Store Purchase 2022 - 2023 $15.00 5 Rhema Danquah Yes
63 09/15/2022 at 6:22 pm Didier Monestine dmonestine@gmail.com 7139270628 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Zoey Monestine No
64 09/15/2022 at 6:22 pm Melondy Monestine no.1bizneswoman@gmail.com 4438393761 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Zoey Monestine Yes
65 09/15/2022 at 1:43 pm Ryan Hikel hikelrw@gmail.com 4432770566 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Avery Hikel No
66 09/15/2022 at 1:43 pm Stephanie Hikel smhikel@gmail.com 4102361226 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Avery Hikel Yes
67 09/15/2022 at 10:36 am James Stepanek jjstepanek@hotmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 Ryan Stepanek Yes
68 09/15/2022 at 10:36 am Laura Stepanek lmagurk@hotmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 Ryan Stepanek Yes
69 09/15/2022 at 8:33 am Katie Coffey katherine_coffey@hcpss.org 4103002846 Faculty/Staff Store Purchase 2022 - 2023 $10.00
70 09/15/2022 at 7:36 am Chasity Thompson cnmthomp@icloud.com Parent/Guardian 1052 Check 2022 - 2023 $75.00 4 Noa Thompson No Yes Nicholas Thompson
71 09/15/2022 at 7:33 am Bonyoung Lee kellygu0121@gmail.com Parent/Guardian Cash 2022 - 2023 $37.50 K Aiden Raon Lee Yes Yes
72 09/15/2022 at 7:33 am Scott Lee may4am@gmail.com Parent/Guardian 1912 Check 2022 - 2023 $37.50 K Aiden Raon Lee Yes Yes
73 09/15/2022 at 7:30 am Allyson Jackson ja_jackson@verizon.net Parent/Guardian 2940 Check 2022 - 2023 $30.00 Yes 5 Kyle Jackson
74 09/15/2022 at 7:26 am Chris Bechis chris.bechis@gmail.com Parent/Guardian Cash 2022 - 2023 $15.00 3 June Bechis Yes
75 09/15/2022 at 7:26 am Leslie Bechis leslie.bechis@gmail.com Parent/Guardian 663 Check 2022 - 2023 $15.00 3 June Bechis Yes
76 09/15/2022 at 7:23 am Joseph Greenseid jgreenseid@gmail.com Parent/Guardian Cash 2022 - 2023 $15.00 2 Lily Greenseid Yes
77 09/15/2022 at 7:23 am Jessica Greenseid jessica.greenseid@gmail.com Parent/Guardian 564 Check 2022 - 2023 $15.00 2 Lily Greenseid Yes
78 09/15/2022 at 7:19 am Adrian Loftus acewx333@hotmail.com Parent/Guardian Cash 2022 - 2023 $15.00 4 Diego Loftus No
79 09/15/2022 at 7:19 am Andrea Loftus andruloftus@hotmail.com Parent/Guardian Cash 2022 - 2023 $15.00 4 Diego Loftus Yes
80 09/15/2022 at 7:09 am Tara Persaud tara.persaud31@gmail.com 4434547247 Parent/Guardian Store Purchase 2022 - 2023 $12.00 Yes 3 Avery Persaud
81 09/14/2022 at 9:47 pm Jon Zawodny jonsawodny@gmail.com Parent/Guardian Cash 2022 - 2023 $37.50 2 Olivia Zawodny Yes Yes
82 09/14/2022 at 9:47 pm Vanessa Zawodny vanessa.zawodny@gmail.com Parent/Guardian 230 Check 2022 - 2023 $37.50 2 Olivia Zawodny Yes Yes
83 09/14/2022 at 7:09 pm Jeff Guy Jeffguy@gmail.com 3018441239 Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 Kara Guy Yes 2 Nadia Guy
84 09/14/2022 at 7:09 pm Rebecca Guy rebstill@gmail.com 8048394625 Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 Kara Guy Yes 2 Nadia Guy
85 09/14/2022 at 6:53 pm Mitchell Gutshall Mguts001@verizon.net 2402775384 Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Davey Gutshall No No 1 Ellie Gutshall
86 09/14/2022 at 6:53 pm Marianne Gutshall mgutshall@gmail.com 4434733740 Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Davey Gutshall Yes Yes 1 Ellie Gutshall
87 09/14/2022 at 4:26 pm Talia Skyles talia_skyles@hcpss.org 3019221380 Faculty/Staff Store Purchase 2022 - 2023 $10.00
88 09/14/2022 at 11:50 am Jennifer Tinnirella Jagoodemote@gmail.com 4439040473 Parent/Guardian Store Purchase 2022 - 2023 $15.00 1 Shaylee Tinnirella No
89 09/14/2022 at 11:50 am Anthony Tinnirella ajtinnirella@gmail.com 4102411388 Parent/Guardian Store Purchase 2022 - 2023 $15.00 1 Shaylee Tinnirella No
90 09/13/2022 at 6:48 pm Jason Mabee Jason.mabee1@gmail.com 443-255-4135 Parent/Guardian Store Purchase 2022 - 2023 $15.00 1 Grant Mabee No
91 09/13/2022 at 6:48 pm Adrienne Mabee adrienne.mabee@gmail.com 4434528612 Parent/Guardian Store Purchase 2022 - 2023 $15.00 1 Grant Mabee Yes 5 Bryn Mabee
92 09/13/2022 at 6:45 pm Nicole Gable cmgable37@gmail.com 4436764204 Parent/Guardian Store Purchase 2022 - 2023 $75.00 2 Linzey Gable No No
93 09/13/2022 at 6:02 pm Jennifer Fitzpatrick jenfitz1283@gmail.com 4438785344 Parent/Guardian Store Purchase 2022 - 2023 $12.00 No 1 Devyn Fitzpatrick 3 Brooks Fitzpatrick
94 09/13/2022 at 6:01 pm Abhishek Rege abhishekrege@gmail.com 4104998349 Parent/Guardian Store Purchase 2022 - 2023 $15.00 1 Oorja Rege Yes
95 09/13/2022 at 6:01 pm Avanti Shetye avshetye@gmail.com 2405158469 Parent/Guardian Store Purchase 2022 - 2023 $15.00 1 Oorja Rege Yes
96 09/13/2022 at 5:36 pm Daniel Ji Danielaramji@gmail.com 4438126426 Parent/Guardian Store Purchase 2022 - 2023 $37.50 K Eli Ji Yes No
97 09/13/2022 at 5:36 pm Deborah Yi Deborahmyi@gmail.com 9178818945 Parent/Guardian Store Purchase 2022 - 2023 $37.50 K Eli Ji Yes Yes
98 09/13/2022 at 12:53 pm Laura Rose laura.eva.rose@gmail.com 3307048863 Parent/Guardian Store Purchase 2022 - 2023 $75.00 K Maddox Howe Yes Yes
99 09/12/2022 at 10:01 pm Jeanne DeBoy jdeboy@hcpss.org Faculty/Staff Store Purchase 2022 - 2023 $10.00
100 09/12/2022 at 8:24 pm Amy Bailey amy_bailey@hcpss.org Faculty/Staff Store Purchase 2022 - 2023 $10.00
101 09/12/2022 at 8:15 pm Andrea Pendergast andrea_pendergast@hcpss.org 5514863820 Faculty/Staff Store Purchase 2022 - 2023 $10.00
102 09/12/2022 at 8:15 pm Maddie McErlean madeline_mcerlean@hcpss.org 4103369883 Faculty/Staff Store Purchase 2022 - 2023 $10.00
103 09/12/2022 at 6:11 pm Bill Rodney Brodney@optonline.net Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Samantha Rodney No
104 09/12/2022 at 6:11 pm Donna Rodney gelchiondm@gmail.com 6318480162 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Samantha Rodney Yes
105 09/12/2022 at 4:07 pm Esther Jean-Louis esther_jean-louis@hcpss.org 4438327187 Faculty/Staff Store Purchase 2022 - 2023 $10.00
106 09/12/2022 at 4:00 pm Kyle Robson Kar0880@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 1 Paige Robson Yes
107 09/12/2022 at 4:00 pm Kristina Robson kristinanrobson@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 1 Paige Robson Yes
108 09/12/2022 at 1:19 pm Robert Schmidt Rob.a.schmidt@gmail.com 301-875-2785 Parent/Guardian Store Purchase 2022 - 2023 $37.50 2 Ella Schmidt Yes No
109 09/12/2022 at 1:19 pm Ashley Schmidt ancook85@gmail.com 4105300024 Parent/Guardian Store Purchase 2022 - 2023 $37.50 2 Ella Schmidt Yes No
110 09/12/2022 at 1:04 pm Vinoth kumar Mohan kumar Vinoth.mohank@gmail.com 8607134762 Parent/Guardian Store Purchase 2022 - 2023 $15.00 2 Aditi Vinod Yes
111 09/12/2022 at 1:04 pm Parvadha suganya Manimude parvadha.suganya@gmail.com 8604715173 Parent/Guardian Store Purchase 2022 - 2023 $15.00 2 Aditi Vinod Yes
112 09/12/2022 at 11:52 am Kimberly Young yyoung@bcps.org Grandparent Store Purchase 2022 - 2023 $15.00 4 Sky Burris Yes 2 Sage Burris
113 09/12/2022 at 11:52 am Yardley Young Yardleyyoung@ymail.com 4435400049 Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 Sky Burris Yes 2 Sage Burris
114 09/12/2022 at 10:16 am Joe Murray joseph.c.murray@gmail.com 510-484-1153 Parent/Guardian Store Purchase 2022 - 2023 $37.50 1 Ethan Murray No No
115 09/12/2022 at 10:16 am Carrie Murray carrie.chao.murray@gmail.com 415-846-9941 Parent/Guardian Store Purchase 2022 - 2023 $37.50 1 Ethan Murray Yes Yes
116 09/11/2022 at 4:02 pm Santosh Venkatesha santosh123@gmail.com 443-621-4424 Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Akash Venkatesha Yes No
117 09/11/2022 at 4:02 pm Mona Gahunia mkg112@gmail.com 4435406214 Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Akash Venkatesha Yes Yes
118 09/10/2022 at 8:45 pm Brian Johnson bjohnson31@gmail.com 4109359136 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Grant Johnson Yes
119 09/10/2022 at 8:45 pm Elizabeth Johnson eajohnson621@gmail.com 2404223408 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Grant Johnson Yes
120 09/10/2022 at 7:27 pm Alexander Livieratos Aleclivi@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Paxton livieratos No Yes 2 Thea livieratos
121 09/10/2022 at 7:27 pm Kelly Livieratos kellykm@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Paxton Livieratos Yes Yes 2 Thea Livieratos
122 09/10/2022 at 4:42 pm Laurie Daman ljdaman@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 Elena Daman Yes
123 09/10/2022 at 4:42 pm Kurt Daman kdaman77@gmail.com 4436990849 Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 Elena Daman Yes
124 09/10/2022 at 2:19 pm Thomas Ruo Rrmedoff@yahoo.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Robert Ruo No No 2 Jason Ruo
125 09/10/2022 at 2:19 pm Rachel Ruo rrmedoff@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Robert Ruo No No 2 Jason Ruo
126 09/10/2022 at 1:49 pm Beverly Weber bevy.lynn@gmail.com Parent/Guardian Cash 2022 - 2023 $30.00 Yes 3 Isaac Weber 5 Anderson Weber
127 09/10/2022 at 1:47 pm Akdas Mumtaz akdasmumtaz@gmail.com Parent/Guardian Cash 2022 - 2023 $30.00 Yes K Hiba Mumtaz
128 09/10/2022 at 1:29 pm Tabassum Sarfraz Muminah2011@gmail.com Parent/Guardian Square (BTSP) Check 2022 - 2023 $30.00 Yes 4 Nuraniya Tahir K Tasbiha Tahir
129 09/10/2022 at 1:26 pm Joohee Chae chaejoo84@gmail.com Parent/Guardian Square (BTSP) Check 2022 - 2023 $12.00 No 4 Subeen Oh 3 Seoyeon Oh
130 09/10/2022 at 1:23 pm Jaye Van Acht jayevanacht@gmail.com Parent/Guardian Square (BTSP) Check 2022 - 2023 $75.00 5 Grey Van Acht No Yes Saul Van Acht
131 09/09/2022 at 6:02 pm Erin Coleman 2030erin@gmail.com 4103702508 Faculty/Staff Store Purchase 2022 - 2023 $10.00
132 09/09/2022 at 4:16 pm Jeff Plank jplank3020@gmail.com 4102274952 Parent/Guardian Store Purchase 2022 - 2023 $37.50 5 Whitney Plank No Yes 3 Everett Plank
133 09/09/2022 at 4:16 pm Corinne Plank cplank2225@gmail.com 4106529305 Parent/Guardian Store Purchase 2022 - 2023 $37.50 5 Whitney Plank Yes Yes 3 Everett Plank
134 09/09/2022 at 4:16 pm Corinne Plank cplank1225@gmail.com 4106529305 Parent/Guardian Store Purchase 2022 - 2023 $37.50 5 Whitney Plank Yes Yes 3 Everett Plank
135 09/09/2022 at 4:13 pm Brad Piergrossi Bradpiergrossi@yahoo.com 4109387396 Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Fiona Raftery Piergrossi Yes No 4 Aleena Raftery Piergrossi
136 09/09/2022 at 4:13 pm Martina Raftery tinaraftery@yahoo.com 4438441908 Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Fiona Raftery Piergrossi Yes No 4 Aleena Raftery Piergrossi Brad Piergrossi
137 09/09/2022 at 2:59 pm Patricia Lough Buzzerd Pat.A.Lough@GMAIL.COM 3014520150 Parent/Guardian Store Purchase 2022 - 2023 $15.00 1 Allison Buzzerd No
138 09/09/2022 at 2:59 pm Christian Buzzerd LOUGHBUZZERD@GMAIL.COM 4432543400 Parent/Guardian Store Purchase 2022 - 2023 $15.00 1 Allison Buzzerd Yes
139 09/09/2022 at 8:19 am kevin knott kevin.knott2@gmail.com Parent/Guardian Cash 2022 - 2023 $5.00 No 4 bryan knott 2 chloe knott
140 09/09/2022 at 7:38 am Christina Harold christina_harold@hcpss.org Faculty/Staff Store Purchase 2022 - 2023 $10.00
141 09/08/2022 at 10:35 pm Stephen Senerchia steve@senerchia.com Parent/Guardian Cash 2022 - 2023 $37.50 4 Sofee Senerchia No Yes 1 Mia Senerchia
142 09/08/2022 at 10:35 pm Sara Senerchia sara@senerchia.com Parent/Guardian Cash 2022 - 2023 $37.50 4 Sofee Senerchia Yes Yes 1 Mia Senerchia
143 09/08/2022 at 4:06 pm Xin Li Lixintt.chn@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 1 Hailey Tao Yes Yes 4 Bryan Tao
144 09/08/2022 at 4:06 pm Tao Tao Taotao.chn@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 1 Hailey Tao Yes Yes 4 Bryan Tao
145 09/08/2022 at 2:17 pm Eun-Chung Cintron eun-chung_cintron@hcpss.org Faculty/Staff Store Purchase 2022 - 2023 $10.00
146 09/08/2022 at 10:31 am Josh Ferguson joshuatferguson@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 5 Hailey Ferguson No 3 Evan Ferguson Alex Ferguson K
147 09/08/2022 at 10:31 am Linda Ferguso linda.f.ferguson@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 5 Hailey Ferguson Yes 3 Evan Ferguson Alex Ferguson K
148 09/08/2022 at 8:18 am Kevin Sharpe Ksharpe45@gmail.com 4436236643 Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 Kylie Sharpe No
149 09/08/2022 at 8:18 am Colleen Cavanaugh Csquared27@gmail.com 3152547584 Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 Kylie Sharpe Yes
150 09/08/2022 at 6:55 am Chidimma Agbakwuru chidimmaa@gmail.com Parent/Guardian Cash 2022 - 2023 $37.50 K Elaine Agbakwuru No Yes
151 09/08/2022 at 6:55 am Chinedu Agbakwuru edwuru@gmail.com Parent/Guardian Cash 2022 - 2023 $37.50 K Elaine Agbakwuru No Yes
152 09/07/2022 at 10:47 pm Lily Park insuzzang81@hotmail.com 4437149711 Parent/Guardian Store Purchase 2022 - 2023 $12.00 Yes 4 Nathaniel Park
153 09/07/2022 at 10:07 pm Calvin Ball cball@howardcountymd.gov Community Cash 2022 - 2023 $12.00 No K N/A
154 09/07/2022 at 9:49 pm Maryam Diaz maryamgdiaz@gmail.com Parent/Guardian Cash 2022 - 2023 $37.50 K Samantha Diaz Yes Yes
155 09/07/2022 at 9:49 pm Alvin Diaz alvin1782@yahoo.com Parent/Guardian Cash 2022 - 2023 $37.50 K Samantha Diaz Yes Yes
156 09/07/2022 at 9:32 pm Craig Newcomb cknewcomb@gmail.com 443-896-4412 Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Annelise Newcomb No No 2 Lorelei Newcomb
157 09/07/2022 at 9:32 pm Jennifer Newcomb jflanigan@gmail.com 717-495-4596 Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Annelise Newcomb Yes Yes 2 Lorelei Newcomb
158 09/07/2022 at 7:41 pm Frances Felder franwfelder@gmail.com 4103400988 Parent/Guardian Store Purchase 2022 - 2023 $75.00 5 Delayni Felder Yes Yes
159 09/07/2022 at 7:11 pm Nina Philipsen nm.philipsen@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $12.00 Yes 5 Nora Hetzner
160 09/07/2022 at 6:47 pm David Goggin Dgoggin77@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 1 Emma Goggin No
161 09/07/2022 at 6:47 pm Sara Goggin sgoggin22@gmail.com 6177557387 Parent/Guardian Store Purchase 2022 - 2023 $15.00 1 Emma Goggin Yes
162 09/07/2022 at 6:47 pm Brian Day Briday50@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 1 Ellie Day No No
163 09/07/2022 at 6:47 pm Sarah Day sarahday52@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 1 Ellie day Yes No
164 09/07/2022 at 6:41 pm Dan Notari dnotari44@gmail.com 4103132813 Faculty/Staff Store Purchase 2022 - 2023 $10.00
165 09/07/2022 at 6:04 pm Michael Brewer michaeldbrewer1974@gmail.com 4107030386 Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 Evelyn Brewer No
166 09/07/2022 at 6:04 pm Katherine Brewer katie.cardoni.brewer@gmail.com 7037856121 Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 Evelyn Brewer Yes
167 09/07/2022 at 5:54 pm Seth Groman seth.groman@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 3 Max Groman No No
168 09/07/2022 at 5:54 pm Jenna Groman Jenna.groman@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 3 Max Groman Yes Yes
169 09/07/2022 at 5:05 pm Bob Bergin bobbybergin@hotmail.com Parent/Guardian Cash 2022 - 2023 $37.50 4 Ruby Bergin Yes Yes 3 Grant Bergin
170 09/07/2022 at 5:05 pm Mandy Bergin mandybergin@hotmail.com Parent/Guardian 230 Check 2022 - 2023 $37.50 3 Grant Bergin Yes Yes 4 Ruby Bergin
171 09/07/2022 at 4:58 pm Kevin Cooke kcooke2442@gmail.com Parent/Guardian Cash 2022 - 2023 $37.50 K John Cooke Yes Yes
172 09/07/2022 at 4:58 pm Sarah Cooke sarahcooke2015@gmail.com Parent/Guardian 255 Check 2022 - 2023 $37.50 K John Cooke Yes Yes
173 09/07/2022 at 4:42 pm Kyung Oh klee6256@gmail.com 4436904290 Parent/Guardian Cash 2022 - 2023 $15.00 1 Jeremy Oh No
174 09/07/2022 at 4:42 pm Thomas Oh yoojaeha@hotmail.com Parent/Guardian 308 Check 2022 - 2023 $15.00 1 Jeremy Oh No
175 09/07/2022 at 1:45 pm Lucas Grace Lukeandlinds@comcast.net 4437456636 Parent/Guardian Store Purchase 2022 - 2023 $37.50 1 Kylie Grace Yes Yes K Mackenzie Grace
176 09/07/2022 at 1:45 pm Lindsay Grace lindsaypickett24@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 1 Kylie Grace Yes Yes K Mackenzie Grace
177 09/07/2022 at 11:28 am ANISH SHAIKH anish786@gmail.com 4109055706 Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 MohammadAamir Shaikh Yes
178 09/07/2022 at 11:28 am HINA SHAIKH hina7860@gmail.com 4439850708 Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 MohammadAamir Shaikh Yes ANISH SHAIKH
179 09/07/2022 at 9:28 am Melissa Orgera melissa_orgera@hcpss.org Faculty/Staff Store Purchase 2022 - 2023 $10.00 No
180 09/06/2022 at 9:14 pm Michele Barron mlbarron10@gmail.com 4109250146 Faculty/Staff Store Purchase 2022 - 2023 $10.00
181 09/06/2022 at 8:14 pm Tim Kelley Tkelley9175@gmail.com 410-925-2283 Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 Jack Kelley No
182 09/06/2022 at 8:14 pm Carrie Kelley Ckelley917@yahoo.com 410-206-9490 Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 Jack Kelley No
183 09/06/2022 at 5:36 pm Justin Ford 22jayferd@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 2 Kathryn Ford No K Owen Ford
184 09/06/2022 at 5:36 pm Jennifer Ford jmpiechocki@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 2 Kathryn Ford Yes K Owen Ford
185 09/06/2022 at 4:18 pm Jimmy Brown tarheel931@gmail.com 706-267-8547 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Sullivan Brown No
186 09/06/2022 at 4:18 pm Mary Brown marbear610@yahoo.com 706-267-9457 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Sullivan Brown Yes
187 09/06/2022 at 3:46 pm Sarah Fauver sarah_fauver@hcpss.org 4438124299 Faculty/Staff Store Purchase 2022 - 2023 $10.00
188 09/06/2022 at 1:59 pm Amy Leisner Amy_Leisner@hcpss.org 443-603-4343 Faculty/Staff Store Purchase 2022 - 2023 $10.00
189 09/06/2022 at 1:57 pm Rob Davis robraydavis@gmail.com 2672535568 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Drew Davis No
190 09/06/2022 at 1:57 pm Amala Davis amaladavis75@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Drew Davis Yes Drew Davis
191 09/06/2022 at 1:40 pm Max Fiallos maxfiallos@gmail.com 4434694191 Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Sebastian Fiallos No No 3 Natalia Fiallos
192 09/06/2022 at 1:40 pm Telma Batres telmabatres@gmail.com 4434227784 Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Sebastian Fiallos Yes Yes 3 Natalia Fiallos
193 09/06/2022 at 12:25 pm Drew Petrella vapetrella@gmail.com 2405053266 Parent/Guardian Store Purchase 2022 - 2023 $37.50 3 Vance Petrella No Yes
194 09/06/2022 at 12:25 pm Liz Petrella petrella.liz@gmail.com 3015128186 Parent/Guardian Store Purchase 2022 - 2023 $37.50 3 Vance Petrella Yes Yes
195 09/06/2022 at 12:17 pm Jessica Roy-Harrison Roy-Harrison jroyharrison@gmail.com 4348254611 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Maximus Bridges Yes 3 Alora Bridges
196 09/06/2022 at 12:17 pm David Bridges dobridges@me.com 4349890736 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 David Bridges Yes 3 Maximus Bridges Alora Bridges
197 09/05/2022 at 9:44 pm Shelly Post shellylpost@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $12.00 Yes 4 Naomi Post 2 Aila Post
198 09/05/2022 at 8:17 pm Kee Jang kwjang28@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Nathan Jang No
199 09/05/2022 at 8:17 pm Kee Jang anajang65@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Nathan Jang Yes
200 09/05/2022 at 7:38 am Preston Schoenly lisacass@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 3 Nathan Schoenly No No Mason Schoenly
201 09/05/2022 at 7:38 am Lisa Schoenly lisaschoenly@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 3 Nathan Schoenly Yes Yes 1 Mason Schoenly
202 09/04/2022 at 8:10 pm Kevin Drummond 4437948245 Parent/Guardian Store Purchase 2022 - 2023 $37.50 5 Dylan Drummond No No
203 09/04/2022 at 8:10 pm Kasey Drummond kaseydrummond@yahoo.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 5 Dylan Drummond No No
204 09/04/2022 at 12:56 pm Erica Voss ericavoss@yahoo.com 410 844 2496 Parent/Guardian Store Purchase 2022 - 2023 $12.00 Elizabeth Cherry Yes K
205 09/04/2022 at 12:03 pm Scott Hays Sahays12@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 Hailey No
206 09/04/2022 at 12:03 pm Miriam Hays mmhays9@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 Hailey Hays No 2 Payton Hays
207 09/04/2022 at 11:36 am Chris Rosas Christopher_rosas@hcpss.org Parent/Guardian Store Purchase 2022 - 2023 $15.00 5 Nicki Rosas No
208 09/04/2022 at 11:36 am Beth Rosas Beth_Rosas@hcpss.org 3017689171 Parent/Guardian Store Purchase 2022 - 2023 $15.00 5 Nicki Rosas Yes
209 09/03/2022 at 9:46 pm Christa Marsico christa_marsico@hcpss.org 4432859415 Faculty/Staff Store Purchase 2022 - 2023 $10.00
210 09/03/2022 at 9:20 pm Kevin Rodkey Kevin.rodkey@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 1 Grace Rodkey No
211 09/03/2022 at 9:20 pm Erika Rodkey erika.rodkey@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 1 Grace Rodkey Yes
212 09/03/2022 at 12:17 pm Bhavik Hukmani b2hukmani@yahoo.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 Damian Hukmani No
213 09/03/2022 at 12:17 pm Kelly Hukmani kehukmani@yahoo.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 Damian Hukmani No
214 09/03/2022 at 12:10 pm Gary Smith gsmith072608@gmail.com 4104598056 Parent/Guardian Store Purchase 2022 - 2023 $37.50 2 Oscar Smith No Yes K Laura Smith
215 09/03/2022 at 12:10 pm Sadie Smith smatarazzosmith@gmail.com 4109168430 Parent/Guardian Store Purchase 2022 - 2023 $37.50 2 Oscar Smith Yes Yes K Laura Smith
216 09/03/2022 at 11:38 am Michael Moskowitz mjmoskowitz@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 Anya Moskowitz No
217 09/03/2022 at 11:38 am Sayli Moskowitz sayliw@gmail.com 2024863103 Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 Anya Moskowitz Yes
218 09/03/2022 at 9:19 am Jennifer Olchowski jenniferparandian@yahoo.com 4435403138 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Charlotte Olchowski Yes
219 09/03/2022 at 9:19 am Adam Olchowski olchowskia@yahoo.com 4103823364 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Charlotte Olchowski No Jennifer Olchowski
220 09/03/2022 at 9:12 am Roxi Da Silva Roxitoo@gmail.com 443-799-9551 Parent/Guardian Store Purchase 2022 - 2023 $15.00 K Giovanni Da Silva Yes
221 09/03/2022 at 9:12 am Diego Da Silva Sumoamor@gmail.com 410-204-2880 Parent/Guardian Store Purchase 2022 - 2023 $15.00 K Giovanni Da Silva Yes
222 09/03/2022 at 8:56 am Michael McCormick mmccor12@gmail.com 4109677949 Parent/Guardian Store Purchase 2022 - 2023 $37.50 1 Liana McCormick No Yes
223 09/03/2022 at 8:56 am Heather McCormick hurdheather87@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 1 Liana McCormick Yes Yes Mike McCormick
224 09/02/2022 at 10:07 pm Richard Cresswell rcresswell@gmail.com 443-621-3307 Parent/Guardian Store Purchase 2022 - 2023 $37.50 5 Logan Cresswell No No 3 Kalina Cresswell
225 09/02/2022 at 10:07 pm Kasandra Cresswell kasandracresswell@gmail.com 301-502-7037 Parent/Guardian Store Purchase 2022 - 2023 $37.50 5 Logan Cresswell No Yes 3 Kalina Cresswell
226 09/02/2022 at 4:20 pm Glenn Wolfe zlonewolfe@gmail.com 2069204947 Parent/Guardian Store Purchase 2022 - 2023 $37.50 3 Ethan Wolfe No No K Jackson Wolfe
227 09/02/2022 at 4:20 pm Jamie Wolfe rainyjamie8@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 3 Ethan Wolfe Yes Yes K Jackson Wolfe Jamie Wolfe
228 09/02/2022 at 3:14 pm Maryiam Cutlerywala busybeeqk786@yahoo.com 443-670-6555 Faculty/Staff Cash 2022 - 2023 $10.00
229 09/02/2022 at 10:50 am Alan Kramer ackramer@hotmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 5 Calista Kramer No
230 09/02/2022 at 10:50 am Angie Kramer angela.l.kramer@gmail.com 4108186622 Parent/Guardian Store Purchase 2022 - 2023 $15.00 5 Calista Kramer Yes
231 09/02/2022 at 7:43 am Mark Den Herder Mdherder000@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 5 Emmma Den Herder No
232 09/02/2022 at 7:43 am Christine Den Herder Cdenherder@gmail.com 613-967-3159 Parent/Guardian Store Purchase 2022 - 2023 $15.00 5 Emma Den Herder Yes
233 09/01/2022 at 9:28 pm Adam Fisher adam.fisher.personal@gmail.com 4436778847 Parent/Guardian Store Purchase 2022 - 2023 $37.50 5 Ruby Fisher No No 3 Gary Fisher
234 09/01/2022 at 9:28 pm Jane Fisher jane.gribble@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 5 Ruby Fisher No No 3 Gary Fisher Jane R Fisher
235 09/01/2022 at 9:22 pm Christian Vainieri Vainiericm@gmail.com 9179231531 Parent/Guardian Store Purchase 2022 - 2023 $37.50 5 Milo Vainieri Yes No 5 Emmett Vainierj
236 09/01/2022 at 9:22 pm EMILY VAINIERI thepiendak@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 5 Milo Vainieri Yes Yes 5 Emmett Vainieri
237 09/01/2022 at 9:22 pm EMILY VAINIERI emily.vainieri1@maryland.gov Parent/Guardian Store Purchase 2022 - 2023 $37.50 5 Milo Vainieri Yes Yes 5 Emmett Vainieri
238 09/01/2022 at 7:53 pm Harris Gofstein Hascogo@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Juliet Gofstein No No
239 09/01/2022 at 7:53 pm Danielle Gofstein danielle.steiner@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Juliet Gofstein Yes Yes
240 09/01/2022 at 6:31 pm Rachel Haak ocjetskimom@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $12.00 Rose Haak Yes 5
241 09/01/2022 at 4:02 pm Brittany Gutierrez brittanyegutierrez@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $12.00 Andres Gutierrez Yes Marcelo Gutierrez 3 1
242 09/01/2022 at 4:02 pm Eric Nolan nolanericj@gmail.com 2543835516 Parent/Guardian Store Purchase 2022 - 2023 $15.00 1 Jacob Nolan No
243 09/01/2022 at 4:02 pm Dana Nolan Dana.s.nolan@gmail.com 9089024102 Parent/Guardian Store Purchase 2022 - 2023 $15.00 1 Jacob Nolan Yes
244 09/01/2022 at 2:44 pm Jackie DeBella jacquelyn_debella@hcpss.org 4103135000 Faculty/Staff Store Purchase 2022 - 2023 $10.00
245 09/01/2022 at 2:41 pm Amanda Diaz Amanda_diaz@hcpss.org 4107074576 Faculty/Staff Store Purchase 2022 - 2023 $10.00
246 08/31/2022 at 8:21 pm Chad Van Patten cvanpatten@sumologic.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 K Eli Van Patten No No 3 Isaac Van Patten
247 08/31/2022 at 8:21 pm Elizabeth Van Patten elizabethvanpatten@gmail.com 4436522861 Parent/Guardian Store Purchase 2022 - 2023 $37.50 K Eli Van Patten Yes Yes 3 Isaac Van Patten Chad Van Patten
248 08/31/2022 at 4:43 pm Patrick Devine m9adevip@yahoo.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Parker No No K Savannah
249 08/31/2022 at 4:43 pm Jennifer Devine jlmgls@gmail.com 4437451851 Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Parker Devine Yes Yes K Savannah Devine Patrick d Devine
250 08/31/2022 at 2:13 pm JeeMin Lee jeemin_lee@hcpss.org Faculty/Staff Store Purchase 2022 - 2023 $10.00
251 08/31/2022 at 1:13 pm Sharon Nath sbn5160@gmail.com 4432543389 Parent/Guardian Store Purchase 2022 - 2023 $12.00 Brayden Nath Yes 4
252 08/31/2022 at 12:42 pm Thomas Noble thomas.m.noble@gmail.com 410-205-9170 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Joseph Noble No 1 Tucker Noble
253 08/31/2022 at 12:42 pm Leela Noble lcollins802@gmail.com 4434650837 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Joseph Noble Yes 1 Tucker Noble Leela Noble
254 08/31/2022 at 11:49 am Reddy N Apoori anr747@yahoo.com 5712750943 Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 Aditya Apoori No
255 08/31/2022 at 11:49 am Latha Ramachandran latha2310@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 4 Aditya Apoori No
256 08/31/2022 at 11:14 am Erin Fowler Erin_n_fowler@hcpss.org Faculty/Staff Store Purchase 2022 - 2023 $10.00
257 08/31/2022 at 10:55 am Matthew Maschal mmdrummerjpc@yahoo.com 4435276276 Parent/Guardian Store Purchase 2022 - 2023 $37.50 2 Chelsea Harumi Maschal Yes Yes
258 08/31/2022 at 10:55 am Sayuri Kamimura sayurikamimura@hotmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 2 Chelsea Harumi Maschal Yes Yes matthew r maschal
259 08/31/2022 at 10:42 am David Kane Dkane417@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 2 Mollie Kane Yes Yes K Isla Kane
260 08/31/2022 at 10:42 am Christina Kane Christinam.kane@gmail.com 4436671518 Parent/Guardian Store Purchase 2022 - 2023 $37.50 2 Mollie Kane Yes Yes K Isla Kane
261 08/31/2022 at 9:31 am Michael Eitelman eitelmanm@gmail.com 9105839045 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Aaron Mason No 3 Gabriel Eitelman Sean Eitelman 5
262 08/31/2022 at 9:31 am Megan Mason meganmason1@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Aaron Mason Yes 3 Gabriel Eitelman Sean Eitelman 5
263 08/31/2022 at 9:23 am Becky Poirier rebecca_poirier@hcpss.org Faculty/Staff Store Purchase 2022 - 2023 $10.00
264 08/31/2022 at 7:33 am Kelli Byle kbyle@hcpss.org Faculty/Staff Store Purchase 2022 - 2023 $10.00
265 08/30/2022 at 9:31 pm Natalie Blake Natalie_Blake@hcpss.org 2402155990 Faculty/Staff Store Purchase 2022 - 2023 $10.00
266 08/30/2022 at 6:32 pm Keegan Tozaki keegantozaki@me.com 3016765330 Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Vera Nieto Yes No
267 08/30/2022 at 6:32 pm Jaclyn Tozaki avmomrn@gmail.com 2026791758 Parent/Guardian Store Purchase 2022 - 2023 $37.50 4 Vera Nieto Yes No
268 08/30/2022 at 4:37 pm Vanessa Lichliter vanessa_lichliter@hcpss.org 4438647995 Faculty/Staff Store Purchase 2022 - 2023 $10.00
269 08/30/2022 at 3:37 pm Kelly Pavlic Kelly_pavlic@hcpss.org 7246009240 Faculty/Staff Store Purchase 2022 - 2023 $10.00
270 08/30/2022 at 3:17 pm Kelly Rippeon kelly_rippeon@hcpss.org Faculty/Staff Store Purchase 2022 - 2023 $10.00
271 08/30/2022 at 2:41 pm Elizabeth Taylor elizabeth_taylor@hcpss.org Faculty/Staff Store Purchase 2022 - 2023 $10.00
272 08/30/2022 at 1:14 pm Pieter Baker pieter.baker@gmail.com 7606705130 Parent/Guardian Store Purchase 2022 - 2023 $15.00 K Juliette Baker No 2 Max Baker
273 08/30/2022 at 1:14 pm Monica Baker monicarosebaker@gmail.com 7605226514 Parent/Guardian Store Purchase 2022 - 2023 $15.00 K Juliette Baker Yes 2 Max Baker Pieter Baker
274 08/28/2022 at 7:13 pm Paul Halvorsen paul@halvo.me Parent/Guardian Cash 2022 - 2023 $37.50 1 David Halvorsen Yes No 3 Lily Halvorsen
275 08/28/2022 at 7:13 pm Meg Halvorsen meg.halvorsen@gmail.com Parent/Guardian Cash 2022 - 2023 $37.50 1 David Halvorsen Yes No 3 Lily Halvorsen
276 08/28/2022 at 2:55 pm Katrina Vala campingcelebration2014@gmail.com 3522624032 Parent/Guardian Store Purchase 2022 - 2023 $37.50 K Amelia Vala Yes Yes
277 08/28/2022 at 2:55 pm Katrina Vala katrina.hein@gmail.com 717 315 8296 Parent/Guardian Store Purchase 2022 - 2023 $37.50 K Amelia Vala Yes Yes
278 08/28/2022 at 2:10 pm Alan Mejibovsky Mejick24@gmail.com 585-313-1847 Parent/Guardian Store Purchase 2022 - 2023 $15.00 K Keegan Mejibovsky Yes
279 08/28/2022 at 2:10 pm Rachel Mejibovsky Stamanr1@gmail.com 319-521-6890 Parent/Guardian Store Purchase 2022 - 2023 $15.00 K Keegan Mejibovsky Yes
280 08/28/2022 at 9:47 am Scott Lambert slambert815@gmail.com 518-524-0007 Parent/Guardian Store Purchase 2022 - 2023 $15.00 1 Ella Rachel Lambert No
281 08/28/2022 at 9:47 am Alyssa Lambert alyssa.litman@gmail.com 215-833-8085 Parent/Guardian Store Purchase 2022 - 2023 $15.00 1 Ella Rachel Lambert Yes
282 08/26/2022 at 9:40 pm Brandon Lawton lawton.brandon@gmail.com 4436830446 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Mae Lawton Yes
283 08/26/2022 at 9:40 pm Pey Lian Lim p3y1i4n@gmail.com 4436830577 Parent/Guardian Store Purchase 2022 - 2023 $15.00 3 Mae Lawton Yes
284 08/26/2022 at 9:25 am Rebecca Care rebecca_care@hcpss.org 4109788063 Faculty/Staff Store Purchase 2022 - 2023 $10.00
285 08/26/2022 at 7:10 am Christina Harkness christina_harkness@hcpss.org 4439203138 Faculty/Staff Store Purchase 2022 - 2023 $10.00
286 08/25/2022 at 10:19 pm John Ballman xjohnballx@yahoo.com 7142251447 Parent/Guardian Store Purchase 2022 - 2023 $37.50 3 John Ballman Yes No
287 08/25/2022 at 10:19 pm Megan Ballman meg.ballman@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 3 John Ballman Yes No
288 08/25/2022 at 9:54 pm Kevin Foster kevin.h.foster@gmail.com 8609174683 Parent/Guardian Store Purchase 2022 - 2023 $37.50 K Ashton Foster Yes No
289 08/25/2022 at 9:54 pm Rebecca Foster becca.l.foster@gmail.com 6033054221 Faculty/Staff Store Purchase 2022 - 2023 $37.50 K Ashton Foster Yes Yes
290 08/25/2022 at 9:32 pm Brian Scully bjscully4@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 5 Donovan Scully Yes Yes 2 Mairead Scully
291 08/25/2022 at 9:32 pm Tara Scully taramscully@gmail.com 3012214171 Parent/Guardian Store Purchase 2022 - 2023 $37.50 5 Donovan Scully Yes Yes 2 Mairead Scully
292 08/25/2022 at 9:32 pm Glenn Van Scyoc gevanscyoc@yahoo.com 4104932399 Parent/Guardian Store Purchase 2022 - 2023 $37.50 K Sophia Braunstein Yes Yes
293 08/25/2022 at 9:32 pm Kerstin Braunstein kerstin.braunstein@gmail.com 4439098503 Parent/Guardian Store Purchase 2022 - 2023 $37.50 K Sophia Braunstein Yes Yes
294 08/25/2022 at 7:27 pm Josh Burns burnsie42@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 3 Taylor Burns No No 1 Jackson Burns Burns Taylor
295 08/25/2022 at 7:27 pm Tiffany Burns tmb926@yahoo.com 2406456887 Parent/Guardian Store Purchase 2022 - 2023 $37.50 3 Taylor Burns No Yes 1 Jackson Burns Burns Taylor
296 08/25/2022 at 12:42 pm Katelyn Niu katelyn.y.niu@gmail.com 4109164158 Parent/Guardian Store Purchase 2022 - 2023 $37.50 K Alexander Yang Yes Yes
297 08/25/2022 at 12:42 pm Kevin Yang kevin.r.yang@gmail.com 4107363596 Parent/Guardian Store Purchase 2022 - 2023 $37.50 K Alexander Yang Yes Yes
298 08/25/2022 at 9:45 am Chad Morris Morris1175@gmail.com 4108046385 Parent/Guardian Store Purchase 2022 - 2023 $15.00 K Nora Morris Yes Beckykaymorris@gmail.com Morris Becky
299 08/25/2022 at 9:45 am Rebecca Morris beckykaymorris@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 K Nora Morris Yes Morris1175@gmail.com Morris Chad
300 08/25/2022 at 9:44 am Mike Elwell mrmikeelwell@gmail.com 4109523585 Parent/Guardian Store Purchase 2022 - 2023 $37.50 K Waverly Elwell Yes Yes
301 08/25/2022 at 9:44 am Sarah Elwell sarahkelwell0927@gmail.com 4102068615 Parent/Guardian Store Purchase 2022 - 2023 $37.50 K Waverly Elwell Yes Yes
302 08/24/2022 at 6:42 pm Shira Levy ryanmlevy@gmail.com 4104935320 Parent/Guardian Store Purchase 2022 - 2023 $15.00 2 Maxwell Levy Yes K Miles Levy
303 08/24/2022 at 6:42 pm Shira Levy shirarlevy@gmail.com 4437425566 Parent/Guardian Store Purchase 2022 - 2023 $15.00 2 Maxwell Levy Yes K Miles Levy ryanmlevy@gmail.com Levy Ryan
304 08/24/2022 at 6:41 pm Michael Bennett Bennettmichael3@gmail.com 4438120216 Parent/Guardian Store Purchase 2022 - 2023 $15.00 K Reese Bennett Yes 3 Chase Bennett bennettmichael3@gmail.com Bennett Michael
305 08/24/2022 at 6:41 pm Meghan Bennett barrmn@yahoo.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 K Reese Bennett Yes 3 Chase Bennett barrmn@yahoo.com Bennett Meghan
306 08/24/2022 at 2:46 pm Eric Wood clemsoncrab@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 K Spencer Wood No Yes
307 08/24/2022 at 2:46 pm Kim Wood kimberlymariewood@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 K Spencer Wood Yes Yes
308 08/24/2022 at 6:43 am Tolly Peddicord tolly_peddicord@hcpss.org 410-591-9507 Faculty/Staff Store Purchase 2022 - 2023 $10.00
309 08/24/2022 at 5:42 am Kathleen Griffith Kathleen_griffith@hcpss.org 4102074776 Faculty/Staff Store Purchase 2022 - 2023 $10.00
310 08/22/2022 at 12:17 pm Cindy Chen qixin_chen@hcpss.org 4438519277 Faculty/Staff Store Purchase 2022 - 2023 $10.00
311 08/21/2022 at 2:12 pm John Hopkins Jfhopkins01@hotmail.com Parent/Guardian Store Purchase 2022 - 2023 $37.50 3 Benjamin Hopkins No Yes
312 08/21/2022 at 2:12 pm Jennifer Hopkins Piccolag8r@hotmail.com 3212460421 Parent/Guardian Store Purchase 2022 - 2023 $37.50 3 Benjamin Hopkins Yes Yes Jfhopkins01@hotmail.com Hopkins John
313 08/18/2022 at 1:24 am Chris Miles cmiles4@aol.com Parent/Guardian Cash 2022 - 2023 $5.00 No
314 08/18/2022 at 1:22 am Justin Callaway justin.c.callaway@gmail.com Parent/Guardian Cash 2022 - 2023 $5.00 No
315 08/18/2022 at 1:21 am Doug Cherneski doug.cherneski@gmail.com Parent/Guardian Cash 2022 - 2023 $5.00 No
316 08/17/2022 at 7:58 pm Margaret Fischer margaret_fischer@hcpss.org 410-313-2813 Faculty/Staff Store Purchase 2022 - 2023 $10.00
317 08/17/2022 at 4:48 pm Michael O'Neill mponeill84@gmail.com 4103024802 Parent/Guardian Store Purchase 2022 - 2023 $37.50 K Maxwell O'Neill Yes Yes
318 08/17/2022 at 4:48 pm Katherine O'Neill karaoneill523@gmail.com 4102180624 Parent/Guardian Store Purchase 2022 - 2023 $37.50 K Maxwell O'Neill Yes Yes
319 08/17/2022 at 2:55 pm Harish Krishnaswamy harish.swamy@gmail.com 6092731776 Parent/Guardian Store Purchase 2022 - 2023 $37.50 K Arvin Krishnaswamy Yes Yes
320 08/17/2022 at 2:55 pm Ashwini Anjanappa ashwini.a@gmail.com 4102076273 Parent/Guardian Store Purchase 2022 - 2023 $37.50 K Arvin Krishnaswamy Yes Yes
321 08/17/2022 at 10:18 am Jordan Wilson JordanWilson14@gmail.com 240-460-8531 Parent/Guardian Store Purchase 2022 - 2023 $15.00 2 Ava Wilson No
322 08/17/2022 at 10:18 am Tara Wilson TaraWilson0212@gmail.com 410-245-7398 Parent/Guardian Store Purchase 2022 - 2023 $15.00 2 Ava Wilson Yes JordanWilson14@gmail.com Wilson Jordan
323 08/15/2022 at 10:04 am Elton Edinborough eltonseba2014@gmail.com 301-873-8022 Parent/Guardian Store Purchase 2022 - 2023 $37.50 K Mena Kurian Edinborough Yes Yes
324 08/15/2022 at 10:04 am Seba Kurian seba.kurian@gmail.com 832-603-0301 Parent/Guardian Store Purchase 2022 - 2023 $37.50 K Mena Kurian Edinborough Yes Yes
325 08/14/2022 at 6:44 pm Steve Sansone Sansone50@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $15.00 1 Samantha Sansone No
326 08/14/2022 at 6:44 pm Lauren Sansone Lauren.c.sansone@gmail.com 4433264535 Parent/Guardian Store Purchase 2022 - 2023 $15.00 1 Samantha Sansone Yes Sansone50@gmail.com Sansone Steve
327 08/10/2022 at 9:07 am Holly Miles hollymiles8@gmail.com Faculty/Staff Cash 2022 - 2023 $75.00 1 Kinslie Miles cmiles4@aol.com Miles Chris
328 08/09/2022 at 11:55 am Ashley Callaway ashley.e.simmons@gmail.com 410-707-8177 Parent/Guardian Store Purchase 2022 - 2023 $30.00 1 Colin Callaway Yes justin.c.callaway@gmail.com Callaway Justin
329 08/08/2022 at 1:46 pm Candace Knott candace.knott@gmail.com Parent/Guardian Store Purchase 2022 - 2023 $30.00 4 Bryan Knott Yes 2 Chloe Knott kevin.knott2@gmail.com Knott Kevin
330 07/21/2022 at 9:33 am Remya Arul remyaarul1@gmail.com 7576604855 Parent/Guardian Store Purchase 2022 - 2023 $30.00 K Kala Cherneski Yes doug.cherneski@gmail.com Cherneski Doug

13
go.mod
View File

@@ -1,15 +1,24 @@
module go-sjles-pta-vote/server module go-sjles-pta-vote
go 1.24.4 go 1.24.4
require github.com/glebarez/go-sqlite v1.22.0 require (
github.com/glebarez/go-sqlite v1.22.0
github.com/golang-jwt/jwt/v5 v5.2.0
github.com/gorilla/mux v1.8.1
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.11.1
)
require ( require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect
github.com/google/uuid v1.5.0 // indirect github.com/google/uuid v1.5.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
golang.org/x/sys v0.15.0 // indirect golang.org/x/sys v0.15.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
modernc.org/libc v1.37.6 // indirect modernc.org/libc v1.37.6 // indirect
modernc.org/mathutil v1.6.0 // indirect modernc.org/mathutil v1.6.0 // indirect
modernc.org/memory v1.7.2 // indirect modernc.org/memory v1.7.2 // indirect

16
go.sum
View File

@@ -1,18 +1,34 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ= github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ=
github.com/glebarez/go-sqlite v1.22.0/go.mod h1:PlBIdHe0+aUEFn+r2/uthrWq4FxbzugL0L8Li6yQJbc= github.com/glebarez/go-sqlite v1.22.0/go.mod h1:PlBIdHe0+aUEFn+r2/uthrWq4FxbzugL0L8Li6yQJbc=
github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw=
github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
modernc.org/libc v1.37.6 h1:orZH3c5wmhIQFTXF+Nt+eeauyd+ZIt2BX6ARe+kD+aw= modernc.org/libc v1.37.6 h1:orZH3c5wmhIQFTXF+Nt+eeauyd+ZIt2BX6ARe+kD+aw=
modernc.org/libc v1.37.6/go.mod h1:YAXkAZ8ktnkCKaN9sw/UDeUVkGYJ/YquGO4FTi5nmHE= modernc.org/libc v1.37.6/go.mod h1:YAXkAZ8ktnkCKaN9sw/UDeUVkGYJ/YquGO4FTi5nmHE=
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=

16
server/common/common.go Normal file
View File

@@ -0,0 +1,16 @@
package common
import (
"encoding/json"
"net/http"
)
const (
DATE_FORMAT = "2006-01-02 15:04:05"
SUCCESS = "success"
)
func SendError(w http.ResponseWriter, errStr string, statusCode int) {
w.WriteHeader(statusCode)
json.NewEncoder(w).Encode(map[string]string{"error": errStr})
}

View File

@@ -1,21 +1,24 @@
package config package config
import ( import (
"encoding/json"
"fmt" "fmt"
"log"
"os" "os"
"strings" "strings"
) )
type Config struct { type Config struct {
DBPath string `json:"db_path"` DBPath string `json:"db_path"`
RedisHost string `json:"redis_host"` RedisHost string `json:"redis_host"`
RedisPassword string `json:"redis_password"` RedisPassword string `json:"redis_password"`
} }
var conf *Config var conf *Config
var conf_path string = ".env"
func GetConfig() *Config { func GetConfig() *Config {
_ = GenerateEnvFileIfNotExists("./sjles-pta-vote.db")
if conf != nil { if conf != nil {
return conf return conf
} }
@@ -23,10 +26,9 @@ func GetConfig() *Config {
conf = &Config{} conf = &Config{}
// TODO: Make this into a ini or toml file // TODO: Make this into a ini or toml file
confgContent, err := os.ReadFile(".env") configContent, err := os.ReadFile(conf_path)
if err != nil { if err != nil {
fmt.Println("Error reading .env file: ", err) log.Printf("Error reading .env file: %v", err)
os.Exit(1) os.Exit(1)
} }
@@ -37,7 +39,7 @@ func GetConfig() *Config {
for _, variable := range envVariables { for _, variable := range envVariables {
if strings.Contains(variable, "=") { if strings.Contains(variable, "=") {
splitVariable := strings.Split(variable, "=") splitVariable := strings.Split(variable, "=")
envMap[splitVariable[0]] = splitVAriable[1] envMap[splitVariable[0]] = splitVariable[1]
} }
} }
@@ -52,13 +54,22 @@ func GetConfig() *Config {
} else if strings.Contains(key, "redis_password") { } else if strings.Contains(key, "redis_password") {
conf.RedisPassword = value conf.RedisPassword = value
} else { } else {
fmt.Println("Error, Unknown key value pair: ", key, " = ", value) log.Printf("Error, Unknown key value pair: %s = %s", key, value)
} }
} }
return conf return conf
} }
func init() { func SetConfig(init_conf *Config) {
conf = GetConfig() conf = init_conf
}
func GenerateEnvFileIfNotExists(dbPath string) error {
_, err := os.Stat(".env")
if err == nil {
return nil
}
envContent := fmt.Sprintf("db_path=\"%s\"\n", dbPath)
return os.WriteFile(".env", []byte(envContent), 0644)
} }

View File

@@ -2,34 +2,67 @@ package db
import ( import (
"database/sql" "database/sql"
"os" "log"
"go-sjles-pta-vote/server/config"
_ "github.com/glebarez/go-sqlite" _ "github.com/glebarez/go-sqlite"
) )
var build_db_query string = `
CREATE TABLE IF NOT EXISTS polls (
id INTEGER PRIMARY KEY,
question TEXT NOT NULL,
member_yes_votes UNSIGNED INT NOT NULL DEFAULT 0,
member_no_votes UNSIGNED INT NOT NULL DEFAULT 0,
non_member_yes_votes UNSIGNED INT NOT NULL DEFAULT 0,
non_member_no_votes UNSIGNED INT NOT NULL DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
expires_at DATETIME
);
CREATE TABLE IF NOT EXISTS voters (
poll_id UNSIGNED INT NOT NULL,
voter_email TEXT NOT NULL,
FOREIGN KEY (poll_id) REFERENCES polls(id),
PRIMARY KEY (poll_id, voter_email)
);
CREATE TABLE IF NOT EXISTS members (
email TEXT NOT NULL,
member_name TEXT,
school_year UNSIGNED INT NOT NULL,
PRIMARY KEY (email, school_year)
);
`
var db *sql.DB var db *sql.DB
func Connect(db_path string) error { func Connect() (*sql.DB, error) {
var err error db_config := config.GetConfig()
db, err = sql.Open("sqlite", db_path)
db, err := sql.Open("sqlite", db_config.DBPath)
if err != nil { if err != nil {
return err log.Printf("Error opening database: %v", err)
return nil, err
} }
sql_create, err := os.ReadFile("./db_format.sql") _, err = db.Exec(build_db_query)
if err != nil { if err != nil {
return err log.Printf("Error updating schema: %v", err)
_ = db.Close()
return nil, err
} }
_, err = db.Exec(string(sql_create)) return db, nil
return err
} }
func Close() { func Close() {
if db != nil { if db != nil {
_ = db.Close() err := db.Close()
if err != nil {
log.Printf("Error closing database: %v", err)
}
} }
} }

View File

@@ -1,24 +0,0 @@
CREATE TABLE IF NOT EXISTS polls (
id INTEGER PRIMARY KEY,
question TEXT NOT NULL,
member_yes_votes UNSIGNED INT NOT NULL,
member_no_votes UNSIGNED INT NOT NULL,
non_member_yes_votes UNSIGNED INT NOT NULL,
non_member_no_votes UNSIGNED INT NOT NULL,
created_at DATETIME,
updated_at DATETIME,
expires_at DATETIME
);
CREATE TABLE IF NOT EXISTS voters (
poll_id UNSIGNED INT NOT NULL,
voter_email TEXT NOT NULL,
FOREIGN KEY (poll_id) REFERENCES polls(id),
PRIMARY KEY (poll_id, voter_email)
);
CREATE TABLE IF NOT EXISTS members (
email TEXT NOT NULL,
member_name TEXT,
PRIMARY KEY (email)
);

View File

@@ -3,21 +3,26 @@ package db
import ( import (
"os" "os"
"testing" "testing"
"go-sjles-pta-vote/server/config"
) )
func TestConnect(t *testing.T) { func TestConnect(t *testing.T) {
tmp_db, err := os.CreateTemp("", "vote_test.*.db") tmp_db, err := os.CreateTemp("", "vote_test.*.db")
tmp_db_name := tmp_db.Name()
tmp_db.Close()
defer os.Remove(tmp_db_name)
if err != nil { if err != nil {
t.Errorf(`Failed to create temporary db: %v`, err) t.Errorf(`Failed to create temporary db file: %v`, err)
} }
if err := Connect(tmp_db_name); err != nil { init_conf := &config.Config{
t.Errorf(`Failed to create the database at %s: %v`, tmp_db_name, err) DBPath: string(tmp_db.Name()),
}
config.SetConfig(init_conf)
defer os.Remove(tmp_db.Name())
tmp_db.Close()
if _, err := Connect(); err != nil {
t.Errorf(`Failed to create the database: %v`, err)
} }
defer Close() defer Close()

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 845 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
server/icons/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1 @@
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}

226
server/main.go Normal file
View File

@@ -0,0 +1,226 @@
package main
import (
"encoding/json"
"fmt"
"log"
"math/rand"
"net/http"
"os"
"path/filepath"
"strconv"
"time"
"github.com/gorilla/mux"
"go-sjles-pta-vote/server/common"
"go-sjles-pta-vote/server/models"
"go-sjles-pta-vote/server/services"
)
func voteHandler(resWriter http.ResponseWriter, request *http.Request) {
var vote models.Vote
if err := json.NewDecoder(request.Body).Decode(&vote); err != nil {
common.SendError(resWriter, "Invalid JSON", http.StatusBadRequest)
return
}
if err := services.SetVote(&vote); err != nil {
common.SendError(resWriter, "Failed to set vote", http.StatusInternalServerError)
return
}
resWriter.WriteHeader(http.StatusOK)
}
func voteIDHandler(resWriter http.ResponseWriter, request *http.Request) {
vars := mux.Vars(request)
idStr := vars["id"]
id, err := strconv.ParseInt(idStr, 10, 64)
if err != nil {
common.SendError(resWriter, "Invalid poll ID", http.StatusBadRequest)
return
}
vote := models.Vote{
PollId: id,
Email: "example@example.com", // Replace with actual email retrieval logic
Vote: true, // Replace with actual vote retrieval logic
}
err = services.SetVote(&vote)
if err != nil {
common.SendError(resWriter, "Failed to set vote", http.StatusInternalServerError)
return
}
resWriter.WriteHeader(http.StatusOK)
}
func statsHandler(resWriter http.ResponseWriter, request *http.Request) {
if request.Method == http.MethodGet {
filePath := "./server/templates/stats.html"
http.ServeFile(resWriter, request, filePath)
} else if request.Method == http.MethodPost {
vars := mux.Vars(request)
id := vars["id"]
poll, err := services.GetPollByQuestion(id)
if err != nil {
common.SendError(resWriter, "Failed to get poll", http.StatusInternalServerError)
return
}
json.NewEncoder(resWriter).Encode(poll)
} else {
resWriter.WriteHeader(http.StatusMethodNotAllowed)
}
}
func pollsIDHandler(resWriter http.ResponseWriter, request *http.Request) {
vars := mux.Vars(request)
id, err := strconv.ParseInt(vars["id"], 10, 64)
if err != nil {
common.SendError(resWriter, "Invalid poll ID", http.StatusBadRequest)
return
}
poll, err := services.GetPollById(id)
if err == services.ErrPollNotFound {
common.SendError(resWriter, "Poll not found", http.StatusNotFound)
return
} else if err != nil {
common.SendError(resWriter, "Failed to get poll", http.StatusInternalServerError)
return
}
json.NewEncoder(resWriter).Encode(poll)
}
func adminLoginHandler(resWriter http.ResponseWriter, request *http.Request) {
if request.Method != http.MethodPost {
common.SendError(resWriter, "Method not allowed", http.StatusMethodNotAllowed)
return
}
var loginReq services.LoginRequest
if err := json.NewDecoder(request.Body).Decode(&loginReq); err != nil {
common.SendError(resWriter, "Invalid JSON", http.StatusBadRequest)
return
}
// Validate admin credentials
isValid, err := services.ValidateAdminLogin(loginReq.Username, loginReq.Password)
if err != nil {
common.SendError(resWriter, "Invalid username or password", http.StatusBadRequest)
return
}
if !isValid {
common.SendError(resWriter, "Invalid username or password", http.StatusUnauthorized)
return
}
// Generate JWT token
token, err := services.GenerateAuthToken(loginReq.Username)
if err != nil {
common.SendError(resWriter, "Failed to generate auth token", http.StatusInternalServerError)
return
}
resWriter.WriteHeader(http.StatusOK)
json.NewEncoder(resWriter).Encode(services.LoginResponse{
Success: true,
Token: token,
})
}
func initDatabase() error {
// Seed random generator for reproducible results in tests
rand.Seed(42)
polls := []models.Poll{
{
ID: 1,
Question: "Should we increase the budget?",
MemberYes: rand.Int63n(50),
MemberNo: rand.Int63n(50),
NonMemberYes: rand.Int63n(20),
NonMemberNo: rand.Int63n(20),
TotalVotes: int(rand.Int63n(100)),
WhoVoted: []string{"email1@example.com", "email2@example.com", "email3@example.com", "email4@example.com"},
CreatedAt: time.Now().Format(time.RFC3339),
UpdatedAt: time.Now().Format(time.RFC3339),
ExpiresAt: time.Now().Add(24 * time.Hour).Format(time.RFC3339),
},
{
ID: 2,
Question: "Should we hire more staff?",
MemberYes: rand.Int63n(50),
MemberNo: rand.Int63n(50),
NonMemberYes: rand.Int63n(20),
NonMemberNo: rand.Int63n(20),
TotalVotes: int(rand.Int63n(100)),
WhoVoted: []string{"email1@example.com", "email2@example.com", "email3@example.com", "email4@example.com"},
CreatedAt: time.Now().Format(time.RFC3339),
UpdatedAt: time.Now().Format(time.RFC3339),
ExpiresAt: time.Now().Add(24 * time.Hour).Format(time.RFC3339),
},
{
ID: 3,
Question: "Should we renovate the building?",
MemberYes: rand.Int63n(50),
MemberNo: rand.Int63n(50),
NonMemberYes: rand.Int63n(20),
NonMemberNo: rand.Int63n(20),
TotalVotes: int(rand.Int63n(100)),
WhoVoted: []string{"email1@example.com", "email2@example.com", "email3@example.com", "email4@example.com"},
CreatedAt: time.Now().Format(time.RFC3339),
UpdatedAt: time.Now().Format(time.RFC3339),
ExpiresAt: time.Now().Add(24 * time.Hour).Format(time.RFC3339),
},
}
for _, poll := range polls {
if err := services.CreatePollIgnore(&poll); err != nil {
return fmt.Errorf("failed to create poll %d: %v", poll.ID, err)
}
}
return nil
}
func main() {
log.SetOutput(os.Stdout)
log.SetFlags(log.LstdFlags | log.Lshortfile)
// Initialize database with sample data
if err := initDatabase(); err != nil {
log.Fatalf("Failed to initialize database: %v", err)
}
http.HandleFunc("/api/vote", voteHandler)
http.HandleFunc("/api/vote/{id}", voteIDHandler)
http.HandleFunc("/api/stats", statsHandler)
http.HandleFunc("/api/polls/{id}", pollsIDHandler)
http.HandleFunc("/api/admin/new-vote", services.AdminNewVoteHandler)
http.HandleFunc("/api/admin/view-votes", services.AdminViewVoteHandler)
http.HandleFunc("/api/admin/login", adminLoginHandler)
http.HandleFunc("/api/admin/members", services.AdminMembersHandler)
http.HandleFunc("/api/admin/members/view", services.AdminMembersView)
buildPath := filepath.Join(".", "client", "build")
fs := http.FileServer(http.Dir(buildPath))
http.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// If the file exists on disk, let the file server handle it.
if _, err := os.Stat(filepath.Join(buildPath, r.URL.Path)); err == nil {
fs.ServeHTTP(w, r)
return
}
// Otherwise serve index.html (so React Router can handle the route)
http.ServeFile(w, r, filepath.Join(buildPath, "index.html"))
}))
log.Printf("Starting server on :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}

View File

@@ -3,4 +3,5 @@ package models
type Members struct { type Members struct {
Name string `json:"name"` Name string `json:"name"`
Email string `json:"email"` Email string `json:"email"`
SchoolYear int `json:"school_year"`
} }

View File

@@ -1,11 +1,15 @@
package models package models
type Poll struct { type Poll struct {
ID int `json:"id"` ID int64 `json:"id"`
Question string `json:"question"` Question string `json:"question"`
TotalVotes int `json:"total_votes"` MemberYes int64 `json:"member_yes"`
WhoVoted []string `json:"who_voted"` MemberNo int64 `json:"member_no"`
CreatedAt string `json:"created_at"` NonMemberYes int64 `json:"non_member_yes"`
UpdatedAt string `json:"updated_at"` NonMemberNo int64 `json:"non_member_no"`
ExpiresAt string `json:"expires_at"` TotalVotes int `json:"total_votes"`
WhoVoted []string `json:"who_voted"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
ExpiresAt string `json:"expires_at"`
} }

View File

@@ -1,7 +1,7 @@
package models package models
type Vote struct { type Vote struct {
PollID int `json:"poll_id"` PollId int64 `json:"poll_id"`
OptionIndex int `json:"option_index"` Vote bool `json:"vote"`
IsMember bool `json:"is_member"` Email string `json:"email"`
} }

57
server/models/voters.go Normal file
View File

@@ -0,0 +1,57 @@
package models
import (
"go-sjles-pta-vote/server/db"
)
type Voter struct {
Email string `json:"email"`
IsMember bool `json:"is_member"`
YesVote bool `json:"yes_vote"`
}
func GetVoters(pollId int64) ([]Voter, error) {
db_conn, err := db.Connect()
if err != nil {
return nil, err
}
defer db.Close()
rows, err := db_conn.Query(`
SELECT v.voter_email,
CASE
WHEN m.email IS NOT NULL THEN 1
ELSE 0
END AS is_member,
CASE
WHEN p.member_yes_votes + p.non_member_yes_votes > p.member_no_votes + p.non_member_no_votes THEN 1
ELSE 0
END AS yes_vote
FROM voters v
LEFT JOIN members m ON v.voter_email = m.email
LEFT JOIN polls p ON v.poll_id = p.id
WHERE v.poll_id = $1
`, pollId)
if err != nil {
return nil, err
}
defer rows.Close()
var voters []Voter
for rows.Next() {
var voter Voter
var isMember int
var yesVote int
if err := rows.Scan(&voter.Email, &isMember, &yesVote); err != nil {
return nil, err
}
voter.IsMember = isMember == 1
voter.YesVote = yesVote == 1
voters = append(voters, voter)
}
if err := rows.Err(); err != nil {
return nil, err
}
return voters, nil
}

127
server/services/auth.go Normal file
View File

@@ -0,0 +1,127 @@
package services
import (
"crypto/sha256"
"encoding/hex"
"log"
"os"
"strings"
"time"
"github.com/golang-jwt/jwt/v5"
"github.com/pkg/errors"
)
type LoginRequest struct {
Username string `json:"username"`
Password string `json:"password"`
}
type LoginResponse struct {
Success bool `json:"success"`
Token string `json:"token,omitempty"`
Error string `json:"error,omitempty"`
}
var jwtSecret string
func init() {
jwtSecret = os.Getenv("JWT_SECRET")
if jwtSecret == "" {
jwtSecret = "your-secret-key-change-in-production"
log.Println("WARNING: JWT_SECRET not set, using default value. Change this in production!")
}
}
// GetAdminCredentials retrieves admin credentials from environment variables
// Format: ADMIN_USERS=username:password|username2:password2
func getAdminCredentials() map[string]string {
adminUsers := os.Getenv("ADMIN_USERS")
if adminUsers == "" {
// Default admin user (change in production)
adminUsers = "admin:admin"
log.Println("WARNING: ADMIN_USERS not set, using default admin:admin")
}
credentials := make(map[string]string)
for _, userPass := range strings.Split(adminUsers, "|") {
parts := strings.Split(strings.TrimSpace(userPass), ":")
if len(parts) == 2 {
credentials[parts[0]] = parts[1]
}
}
return credentials
}
// hashPassword hashes a password using SHA256
func hashPassword(password string) string {
hash := sha256.Sum256([]byte(password))
return hex.EncodeToString(hash[:])
}
// ValidateAdminLogin checks if the provided username and password are valid
func ValidateAdminLogin(username, password string) (bool, error) {
if username == "" || password == "" {
return false, errors.New("username and password are required")
}
credentials := getAdminCredentials()
storedPassword, exists := credentials[username]
if !exists {
// Return false but not an error for security reasons (don't reveal if user exists)
return false, nil
}
// Compare passwords (you could enhance this with bcrypt in production)
if storedPassword != password {
return false, nil
}
return true, nil
}
// GenerateAuthToken generates a JWT token for an authenticated admin user
func GenerateAuthToken(username string) (string, error) {
claims := jwt.MapClaims{
"username": username,
"exp": time.Now().Add(time.Hour * 24).Unix(), // Token expires in 24 hours
"iat": time.Now().Unix(),
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenString, err := token.SignedString([]byte(jwtSecret))
if err != nil {
return "", errors.Wrap(err, "failed to generate token")
}
return tokenString, nil
}
// VerifyAuthToken verifies a JWT token and returns the username if valid
func VerifyAuthToken(tokenString string) (string, error) {
token, err := jwt.ParseWithClaims(tokenString, &jwt.MapClaims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(jwtSecret), nil
})
if err != nil {
return "", errors.Wrap(err, "failed to parse token")
}
if !token.Valid {
return "", errors.New("invalid token")
}
claims, ok := token.Claims.(*jwt.MapClaims)
if !ok {
return "", errors.New("invalid token claims")
}
username, ok := (*claims)["username"].(string)
if !ok {
return "", errors.New("username not found in token")
}
return username, nil
}

237
server/services/members.go Normal file
View File

@@ -0,0 +1,237 @@
package services
import (
"encoding/csv"
"fmt"
"log"
"strings"
"net/http"
"strconv"
"io/ioutil"
"encoding/json"
"github.com/pkg/errors"
"go-sjles-pta-vote/server/common"
"go-sjles-pta-vote/server/db"
)
type Member struct {
Name string
Email string
}
const BATCH_SIZE = 100
const CVS_FILE_FIELD = "members.csv"
func AdminMembersHandler(resWriter http.ResponseWriter, request *http.Request) {
if request.Method != http.MethodPost {
resWriter.WriteHeader(http.StatusMethodNotAllowed)
return
}
var year int
var err error
if err = request.ParseMultipartForm(10 << 20); err != nil {
common.SendError(resWriter, "Failed to parse multipart form", http.StatusBadRequest)
return
}
year_from_form := request.FormValue("year")
if year_from_form == "" {
common.SendError(resWriter, "Year is required", http.StatusBadRequest)
return
} else {
year, err = strconv.Atoi(year_from_form)
if err != nil {
common.SendError(resWriter, "Invalid year", http.StatusBadRequest)
return
}
}
file, _, err := request.FormFile(CVS_FILE_FIELD)
if err != nil {
common.SendError(resWriter, "Failed to read " + CVS_FILE_FIELD + " file", http.StatusBadRequest)
return
}
defer file.Close()
fileBytes, err := ioutil.ReadAll(file)
if err != nil {
common.SendError(resWriter, "Failed to read " + CVS_FILE_FIELD + " file", http.StatusInternalServerError)
return
}
if err = ParseMembersFromBytes(year, fileBytes); err != nil {
common.SendError(resWriter, "Failed to parse members from CSV", http.StatusBadRequest)
return
}
resWriter.WriteHeader(http.StatusOK)
json.NewEncoder(resWriter).Encode(map[string]bool{common.SUCCESS: true})
}
func AdminMembersView(resWriter http.ResponseWriter, request *http.Request) {
yearStr := request.URL.Query().Get("year")
if yearStr == "" {
common.SendError(resWriter, "Year is required", http.StatusBadRequest)
return
}
year, err := strconv.Atoi(yearStr)
if err != nil {
common.SendError(resWriter, "Invalid year", http.StatusBadRequest)
return
}
members, err := GetMembersByYear(year)
if err != nil {
common.SendError(resWriter, "Failed to get members", http.StatusInternalServerError)
return
}
resWriter.WriteHeader(http.StatusOK)
json.NewEncoder(resWriter).Encode(map[string]interface{}{
common.SUCCESS: true,
"members": members,
})
}
func ParseMembersFromBytes(year int, fileBytes []byte) error {
reader := csv.NewReader(strings.NewReader(string(fileBytes)))
reader.FieldsPerRecord = -1 // Allow variable number of fields per record
records, err := reader.ReadAll()
if err != nil {
return errors.Wrap(err, "failed to read CSV from bytes")
}
var members []Member
for i, record := range records {
if i == 0 {
continue // Skip the first line (column headers)
}
if len(record) < 4 {
continue
}
firstName := strings.TrimSpace(record[1])
lastName := strings.TrimSpace(record[2])
email := strings.TrimSpace(record[3])
members = append(members, Member{
Name: fmt.Sprintf("%s %s", firstName, lastName),
Email: email,
})
if len(record) < 30 {
continue
}
email2 := strings.TrimSpace(record[27])
if email2 != "" {
firstName2 := strings.TrimSpace(record[29])
lastName2 := strings.TrimSpace(record[28])
members = append(members, Member{
Name: fmt.Sprintf("%s %s", firstName2, lastName2),
Email: email2,
})
}
}
return saveMember(year, members)
}
func saveMember(year int, members []Member) error {
insertMembersQuery := `
INSERT OR REPLACE INTO members (email, member_name, school_year)
VALUES ($1, $2, $3)
`
log.Printf("Starting to save %d members for year %d", len(members), year)
db_conn, err := db.Connect()
if err != nil {
return errors.Wrap(err, "failed to connect to database")
}
defer db_conn.Close()
tx, err := db_conn.Begin()
if err != nil {
return errors.Wrap(err, "failed to begin transaction")
}
stmt, err := tx.Prepare(insertMembersQuery)
if err != nil {
tx.Rollback()
return errors.Wrap(err, "failed to prepare statement")
}
defer stmt.Close()
for index, member := range members {
_, err = stmt.Exec(member.Email, member.Name, year)
if err != nil {
tx.Rollback()
return errors.Wrap(err, "failed to execute insert")
}
if (index+1) % BATCH_SIZE == 0 {
err = tx.Commit()
if err != nil {
tx.Rollback()
return errors.Wrap(err, "failed to commit transaction")
}
tx, err = db_conn.Begin()
if err != nil {
return errors.Wrap(err, "failed to begin new transaction")
}
stmt, err = tx.Prepare(insertMembersQuery)
if err != nil {
tx.Rollback()
return errors.Wrap(err, "failed to prepare new statement")
}
}
}
return tx.Commit()
}
func GetMembersByYear(year int) ([]Member, error) {
query := `
SELECT member_name, email
FROM members
WHERE school_year = $1
ORDER BY member_name ASC
`
db_conn, err := db.Connect()
if err != nil {
return nil, errors.Wrap(err, "failed to connect to database")
}
defer db_conn.Close()
rows, err := db_conn.Query(query, year)
if err != nil {
return nil, errors.Wrap(err, "failed to execute query")
}
defer rows.Close()
var members []Member
for rows.Next() {
var member Member
if err := rows.Scan(&member.Name, &member.Email); err != nil {
return nil, errors.Wrap(err, "failed to scan row")
}
members = append(members, member)
}
if err := rows.Err(); err != nil {
return nil, errors.Wrap(err, "row iteration error")
}
return members, nil
}

538
server/services/poll.go Normal file
View File

@@ -0,0 +1,538 @@
package services
import (
"database/sql"
"encoding/json"
"errors"
"log"
"net/http"
"strconv"
"time"
"go-sjles-pta-vote/server/common"
"go-sjles-pta-vote/server/db"
"go-sjles-pta-vote/server/models"
)
var (
ErrQuestionAlreadyExists = errors.New("Question already exists")
ErrQuestionDoesntExist = errors.New("Question does not exist yet")
ErrVoterAlreadyVoted = errors.New("Voter already voted")
ErrPollNotFound = errors.New("Poll not found")
ErrFailedToUpdateVote = errors.New("Failed to update vote")
ErrFailedToDeletePoll = errors.New("Failed to delete poll")
)
const (
DEFAULT_POLL_DURATION_HOURS = 24
)
func AdminNewVoteHandler(resWriter http.ResponseWriter, request *http.Request) {
if request.Method != http.MethodPost {
resWriter.WriteHeader(http.StatusMethodNotAllowed)
return
}
question := request.FormValue("question")
if question == "" {
common.SendError(resWriter, "Question is required", http.StatusBadRequest)
return
}
durationHours := DEFAULT_POLL_DURATION_HOURS
if durationStr := request.FormValue("duration"); durationStr != "" {
var err error
durationHours, err = strconv.Atoi(durationStr)
if err != nil {
common.SendError(resWriter, "Invalid duration", http.StatusBadRequest)
return
}
}
poll := models.Poll{
Question: question,
ExpiresAt: time.Now().Add(time.Duration(durationHours) * time.Hour).Format(common.DATE_FORMAT),
}
_, err := CreatePoll(&poll)
if err != nil {
common.SendError(resWriter, "Failed to create poll", http.StatusInternalServerError)
return
}
resWriter.WriteHeader(http.StatusOK)
json.NewEncoder(resWriter).Encode(map[string]bool{common.SUCCESS: true})
}
func CreatePoll(poll *models.Poll) (int64, error) {
db_conn, err := db.Connect()
if err != nil {
log.Printf("Failed to connect to database: %s", err.Error())
return -1, err
}
defer db.Close()
get_stmt, err := db_conn.Prepare(`
SELECT id
FROM polls
WHERE question == $1
`)
if err != nil {
log.Printf("%s", err.Error())
return -1, err
}
defer get_stmt.Close()
var id int
err = get_stmt.QueryRow(poll.Question).Scan(&id)
if err != nil {
if err != sql.ErrNoRows {
log.Printf("%s", err.Error())
return -1, err
}
return -1, ErrQuestionAlreadyExists
}
stmt, err := db_conn.Prepare(`
INSERT INTO polls (
question,
expires_at
) VALUES (
$1,
$2
) RETURNING ID;
`)
if err != nil {
log.Printf("%s", err.Error())
return -1, err
}
defer stmt.Close()
res, err := stmt.Exec(poll.Question, poll.ExpiresAt)
if err != nil {
log.Printf("%s", err.Error())
return -1, err
}
new_poll_id, err := res.LastInsertId()
return new_poll_id, err
}
func AdminViewVoteHandler(resWriter http.ResponseWriter, request *http.Request) {
if request.Method != http.MethodPost {
resWriter.WriteHeader(http.StatusMethodNotAllowed)
return
}
var polls []models.Poll
var err error
question := request.FormValue("question")
if question == "" {
polls, err = GetAllPolls()
if err != nil {
common.SendError(resWriter, "Failed to get polls", http.StatusInternalServerError)
return
}
} else {
poll, err := GetPollByQuestion(question)
if err != nil {
common.SendError(resWriter, "Failed to get poll question "+question, http.StatusInternalServerError)
return
}
polls = append(polls, *poll)
}
err = json.NewEncoder(resWriter).Encode(polls)
if err != nil {
log.Printf("Error encoding response: %v", err)
common.SendError(resWriter, "Failed to encode polls", http.StatusInternalServerError)
return
}
}
func GetAllPolls() ([]models.Poll, error) {
db_conn, err := db.Connect()
if err != nil {
log.Printf("%s", err.Error())
return nil, err
}
defer db.Close()
get_polls_stmt, err := db_conn.Prepare(`
SELECT
id, question,
member_yes_votes, member_no_votes,
non_member_yes_votes, non_member_no_votes,
created_at, updated_at,
expires_at
FROM polls
`)
if err != nil {
log.Printf("%s", err.Error())
return nil, err
}
defer get_polls_stmt.Close()
rows, err := get_polls_stmt.Query()
if err != nil {
log.Printf("%s", err.Error())
return nil, err
}
defer rows.Close()
var polls []models.Poll
for rows.Next() {
new_poll := models.Poll{}
err = rows.Scan(
&new_poll.ID, &new_poll.Question,
&new_poll.MemberYes, &new_poll.MemberNo,
&new_poll.NonMemberYes, &new_poll.NonMemberNo,
&new_poll.CreatedAt, &new_poll.UpdatedAt,
&new_poll.ExpiresAt,
)
if err != nil {
log.Printf("%s", err.Error())
return nil, err
}
polls = append(polls, new_poll)
}
return polls, nil
}
func GetPollByQuestion(question string) (*models.Poll, error) {
db_conn, err := db.Connect()
if err != nil {
log.Printf("%s", err.Error())
return nil, err
}
defer db.Close()
get_poll_stmt, err := db_conn.Prepare(`
SELECT
id, question,
member_yes_votes, member_no_votes,
non_member_yes_votes, non_member_no_votes,
created_at, updated_at,
expires_at
FROM polls
WHERE question == $1
`)
if err != nil {
log.Printf("%s", err.Error())
return nil, err
}
defer get_poll_stmt.Close()
new_poll := models.Poll{}
err = get_poll_stmt.QueryRow(question).Scan(
&new_poll.ID, &new_poll.Question,
&new_poll.MemberYes, &new_poll.MemberNo,
&new_poll.NonMemberYes, &new_poll.NonMemberNo,
&new_poll.CreatedAt, &new_poll.UpdatedAt,
&new_poll.ExpiresAt,
)
if err == sql.ErrNoRows {
return nil, ErrPollNotFound
} else if err != nil {
log.Printf("%s", err.Error())
return nil, err
}
get_voters_stmt, err := db_conn.Prepare(`
SELECT voter_email
FROM voters
WHERE poll_id == $1
`)
if err != nil {
return nil, err
}
defer get_voters_stmt.Close()
rows, err := get_voters_stmt.Query(new_poll.ID)
for rows.Next() {
var voter_email string
err = rows.Scan(&voter_email)
if err != nil {
log.Printf("%s", err.Error())
return nil, err
}
new_poll.WhoVoted = append(new_poll.WhoVoted, voter_email)
}
return &new_poll, nil
}
func GetPollById(id int64) (*models.Poll, error) {
db_conn, err := db.Connect()
if err != nil {
log.Printf("%s", err.Error())
return nil, err
}
defer db.Close()
get_poll_stmt, err := db_conn.Prepare(`
SELECT
id, question,
member_yes_votes, member_no_votes,
non_member_yes_votes, non_member_no_votes,
created_at, updated_at,
expires_at
FROM polls
WHERE id == $1
`)
if err != nil {
log.Printf("%s", err.Error())
return nil, err
}
defer get_poll_stmt.Close()
new_poll := models.Poll{}
err = get_poll_stmt.QueryRow(id).Scan(
&new_poll.ID, &new_poll.Question,
&new_poll.MemberYes, &new_poll.MemberNo,
&new_poll.NonMemberYes, &new_poll.NonMemberNo,
&new_poll.CreatedAt, &new_poll.UpdatedAt,
&new_poll.ExpiresAt,
)
if err == sql.ErrNoRows {
return nil, ErrPollNotFound
} else if err != nil {
log.Printf("%s", err.Error())
return nil, err
}
return &new_poll, nil
}
func GetAndCreatePollByQuestion(question string) (*models.Poll, error) {
new_poll, err := GetPollByQuestion(question)
if err == ErrPollNotFound {
create_poll := &models.Poll{
Question: question,
ExpiresAt: time.Now().Add(time.Hour * 10).Format(common.DATE_FORMAT),
}
if _, err = CreatePoll(create_poll); err != nil {
return nil, err
}
return GetPollByQuestion(question)
} else if err != nil {
log.Printf("%s", err.Error())
return nil, err
} else {
return new_poll, err
}
}
func SetVote(vote *models.Vote) error {
db_conn, err := db.Connect()
if err != nil {
log.Printf("%s", err.Error())
return err
}
defer db.Close()
set_voter_stmt, err := db_conn.Prepare(`
INSERT OR IGNORE INTO voters
(poll_id, voter_email)
VALUES ($1, $2)
`)
if err != nil {
log.Printf("%s", err.Error())
return err
}
defer set_voter_stmt.Close()
res, err := set_voter_stmt.Exec(vote.PollId, vote.Email)
if err != nil {
log.Printf("%s", err.Error())
return err
} else {
rows_changed, err := res.RowsAffected()
if rows_changed != 1 {
return ErrVoterAlreadyVoted
} else if err != nil {
log.Printf("%s", err.Error())
return err
}
}
is_voter_member_stmt, err := db_conn.Prepare(`
SELECT 1
FROM members
WHERE email == $1
`)
if err != nil {
log.Printf("%s", err.Error())
return err
}
defer is_voter_member_stmt.Close()
var member_check int64
is_member := true
err = is_voter_member_stmt.QueryRow(vote.Email).Scan(&member_check)
if err == sql.ErrNoRows {
is_member = false
} else if err != nil {
log.Printf("%s", err.Error())
return err
}
// Member column name is not dependant on user input
// So it's ok to put it directly in the query
member_column_name := "member_"
if !is_member {
member_column_name = "non_" + member_column_name
}
if vote.Vote {
member_column_name += "yes_votes"
} else {
member_column_name += "no_votes"
}
add_vote_stmt, err := db_conn.Prepare(`
UPDATE polls
SET ` + member_column_name + ` = ` + member_column_name + ` + 1
WHERE id == $1
`)
if err != nil {
log.Printf("%s", err.Error())
return err
}
defer add_vote_stmt.Close()
res, err = add_vote_stmt.Exec(vote.PollId)
if err != nil {
log.Printf("%s", err.Error())
return err
}
if num, err := res.RowsAffected(); num != 1 {
return ErrFailedToUpdateVote
} else if err != nil {
log.Printf("%s", err.Error())
return err
}
return nil
}
// Delete a poll by name
func DeletePollByQuestion(question string) error {
db_conn, err := db.Connect()
if err != nil {
log.Printf("%s", err.Error())
return err
}
defer db.Close()
delete_votes_stmt, err := db_conn.Prepare(`
DELETE FROM voters
WHERE poll_id IN (
SELECT id
FROM polls
WHERE question == $1
)
`)
if err != nil {
log.Printf("%s", err.Error())
return err
}
defer delete_votes_stmt.Close()
_, err = delete_votes_stmt.Exec(question)
if err != nil {
log.Printf("%s", err.Error())
return err
}
delete_poll_stmt, err := db_conn.Prepare(`
DELETE FROM polls
WHERE question == $1
`)
if err != nil {
log.Printf("%s", err.Error())
return err
}
defer delete_poll_stmt.Close()
res, err := delete_poll_stmt.Exec(question)
if err != nil {
log.Printf("%s", err.Error())
return err
}
if num, err := res.RowsAffected(); num != 1 {
return ErrFailedToDeletePoll
} else if err != nil {
log.Printf("%s", err.Error())
return err
}
return nil
}
func CreatePollIgnore(poll *models.Poll) error {
db_conn, err := db.Connect()
if err != nil {
log.Printf("%s", err.Error())
return err
}
defer db.Close()
stmt, err := db_conn.Prepare(`
INSERT OR IGNORE INTO polls (
question,
expires_at,
member_yes_votes,
member_no_votes,
non_member_yes_votes,
non_member_no_votes,
created_at,
updated_at
) VALUES (
$1,
$2,
$3,
$4,
$5,
$6,
$7,
$8
)
`)
if err != nil {
log.Printf("%s", err.Error())
return err
}
defer stmt.Close()
_, err = stmt.Exec(
poll.Question,
poll.ExpiresAt,
poll.MemberYes,
poll.MemberNo,
poll.NonMemberYes,
poll.NonMemberNo,
poll.CreatedAt,
poll.UpdatedAt,
)
if err != nil {
log.Printf("%s", err.Error())
return err
}
return nil
}

View File

@@ -0,0 +1,497 @@
package services
import (
"math/rand"
"os"
"testing"
"time"
"go-sjles-pta-vote/server/config"
"go-sjles-pta-vote/server/db"
"go-sjles-pta-vote/server/models"
)
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-=`~!@#$%^&*()_+[]\\;',./{}|:\"<>?"
var new_members = []struct {
email string
member_name string
}{
{"test1@mail.me", "test1"},
{"test2@mail.me", "test2"},
{"test3@mail.me", "test3"},
{"test4@mail.me", "test4"},
{"test5@mail.me", "test5"},
{"test6@mail.me", "test6"},
{"test7@mail.me", "test7"},
{"test100@mail.me", "test100"},
{"test101@mail.me", "test101"},
{"test102@mail.me", "test102"},
{"test103@mail.me", "test103"},
{"test104@mail.me", "test104"},
{"test105@mail.me", "test105"},
}
var new_polls = []struct {
question string
member_yes_votes int64
member_no_votes int64
non_member_yes_votes int64
non_member_no_votes int64
}{
{"ques1", 1, 2, 3, 4},
{"ques2", 3, 2, 4, 5},
{"ques3", 4, 3, 6, 5},
}
var new_voters = []struct {
poll_id int64
voter_email string
}{
{1, "test1@mail.me"},
{1, "test2@mail.me"},
{1, "test3@mail.me"},
{1, "test10@mail.me"},
{1, "test11@mail.me"},
{1, "test12@mail.me"},
{1, "test13@mail.me"},
{1, "test14@mail.me"},
{1, "test15@mail.me"},
{1, "test16@mail.me"},
{2, "test1@mail.me"},
{2, "test2@mail.me"},
{2, "test3@mail.me"},
{2, "test4@mail.me"},
{2, "test5@mail.me"},
{2, "test10@mail.me"},
{2, "test11@mail.me"},
{2, "test12@mail.me"},
{2, "test13@mail.me"},
{2, "test14@mail.me"},
{2, "test15@mail.me"},
{2, "test16@mail.me"},
{2, "test17@mail.me"},
{2, "test18@mail.me"},
{3, "test1@mail.me"},
{3, "test2@mail.me"},
{3, "test3@mail.me"},
{3, "test4@mail.me"},
{3, "test5@mail.me"},
{3, "test6@mail.me"},
{3, "test7@mail.me"},
{3, "test10@mail.me"},
{3, "test11@mail.me"},
{3, "test12@mail.me"},
{3, "test13@mail.me"},
{3, "test14@mail.me"},
{3, "test15@mail.me"},
{3, "test16@mail.me"},
{3, "test17@mail.me"},
{3, "test18@mail.me"},
{3, "test19@mail.me"},
{3, "test20@mail.me"},
}
func RandString(length int) string {
rand_bytes := make([]byte, length)
for rand_index := range length {
rand_bytes[rand_index] = charset[rand.Intn(len(charset))]
}
return string(rand_bytes)
}
func PreLoadDB() error {
db_conn, err := db.Connect()
if err != nil {
return err
}
defer db.Close()
// Insert members
for i := range new_members {
_, err := db_conn.Exec(`INSERT INTO members (email, member_name, school_year) VALUES (?, ?, ?)`, new_members[i].email, new_members[i].member_name, 2023)
if err != nil {
return err
}
}
// Insert polls
for i := range new_polls {
result, err := db_conn.Exec(`INSERT INTO polls (question, member_yes_votes, member_no_votes, non_member_yes_votes, non_member_no_votes, expires_at) VALUES (?, ?, ?, ?, ?, ?)`, new_polls[i].question, new_polls[i].member_yes_votes, new_polls[i].member_no_votes, new_polls[i].non_member_yes_votes, new_polls[i].non_member_no_votes, time.Now().Add(time.Hour*10).Format("2006-01-02 15:04:05"))
if err != nil {
return err
}
_, err = result.LastInsertId()
if err != nil {
return err
}
}
// Insert voters
for i := range new_voters {
_, err := db_conn.Exec(`INSERT INTO voters (poll_id, voter_email) VALUES (?, ?)`, new_voters[i].poll_id, new_voters[i].voter_email)
if err != nil {
return err
}
}
return nil
}
func TestCreatePoll(t *testing.T) {
parameters := []struct {
question string
table_index int64
}{
{RandString(10) + "1", 1},
{RandString(10) + "2", 2},
{RandString(10) + "3", 3},
{"\"" + RandString(10) + "4", 4},
{"\\\"" + RandString(10) + "5", 5},
{"'" + RandString(10) + "6", 6},
{";" + RandString(10) + "7", 7},
{"\\" + RandString(10) + "8", 8},
}
tmp_db, err := os.CreateTemp("", "vote_test.*.db")
if err != nil {
t.Errorf(`Failed to create temporary db file: %v`, err)
}
init_conf := &config.Config{
DBPath: string(tmp_db.Name()),
}
config.SetConfig(init_conf)
defer os.Remove(tmp_db.Name())
tmp_db.Close()
if _, err := db.Connect(); err != nil {
t.Errorf(`Failed to create the database: %v`, err)
}
for i := range parameters {
create_poll := &models.Poll{
Question: parameters[i].question,
ExpiresAt: time.Now().Add(time.Hour * 10).Format("2006-01-02 15:04:05"),
}
new_poll_id, err := CreatePoll(create_poll)
if err != nil {
t.Errorf(`Failed to create new poll %s: %v`, parameters[i].question, err)
}
if new_poll_id == -1 {
t.Errorf(`Failed to insert %s into table`, parameters[i].question)
}
if new_poll_id != parameters[i].table_index {
t.Errorf(`Incorrect increment in index for %s: expected %d != %d`, parameters[i].question, parameters[i].table_index, new_poll_id)
}
}
}
func TestAlreadyExists(t *testing.T) {
question := "TestQuestion"
tmp_db, err := os.CreateTemp("", "vote_test.*.db")
if err != nil {
t.Errorf(`Failed to create temporary db file: %v`, err)
}
init_conf := &config.Config{
DBPath: string(tmp_db.Name()),
}
config.SetConfig(init_conf)
defer os.Remove(tmp_db.Name())
tmp_db.Close()
if _, err := db.Connect(); err != nil {
t.Errorf(`Failed to create the database: %v`, err)
}
create_poll := &models.Poll{
Question: question,
ExpiresAt: time.Now().Add(time.Hour * 10).Format("2006-01-02 15:04:05"),
}
new_poll, err := CreatePoll(create_poll)
if err != nil {
t.Errorf(`Failed to create new poll %s: %v`, question, err)
}
if new_poll == -1 {
t.Errorf(`Failed to insert %s into table`, question)
}
new_poll, err = CreatePoll(create_poll)
if err != ErrQuestionAlreadyExists {
t.Errorf(`Should have failed adding %s as it already exists`, question)
}
}
func TestGetPollByQuestion(t *testing.T) {
question := "TestQuestion"
tmp_db, err := os.CreateTemp("", "vote_test.*.db")
if err != nil {
t.Errorf(`Failed to create temporary db file: %v`, err)
}
init_conf := &config.Config{
DBPath: string(tmp_db.Name()),
}
config.SetConfig(init_conf)
defer os.Remove(tmp_db.Name())
tmp_db.Close()
if _, err := db.Connect(); err != nil {
t.Errorf(`Failed to create the database: %v`, err)
}
create_poll := &models.Poll{
Question: question,
ExpiresAt: time.Now().Add(time.Hour * 10).Format("2006-01-02 15:04:05"),
}
new_poll, err := CreatePoll(create_poll)
if err != nil {
t.Errorf(`Failed to create new poll %s: %v`, question, err)
}
if new_poll == -1 {
t.Errorf(`Failed to insert %s into table`, question)
}
get_poll, err := GetPollByQuestion(question)
if err != nil {
t.Errorf(`Failed to get the poll %s: %v`, question, err)
}
if get_poll.Question != question {
t.Errorf(`Questions don't match: expected %s: recieved %s`, question, get_poll.Question)
}
}
func TestGetCreatePollByQuestion(t *testing.T) {
parameters := []struct {
question string
table_index int64
}{
{RandString(10) + "1", 1},
{RandString(10) + "2", 2},
{RandString(10) + "3", 3},
{"\"" + RandString(10) + "4", 4},
{"'" + RandString(10) + "5", 5},
{";" + RandString(10) + "6", 6},
}
tmp_db, err := os.CreateTemp("", "vote_test.*.db")
if err != nil {
t.Errorf(`Failed to create temporary db file: %v`, err)
}
init_conf := &config.Config{
DBPath: string(tmp_db.Name()),
}
config.SetConfig(init_conf)
defer os.Remove(tmp_db.Name())
tmp_db.Close()
if _, err := db.Connect(); err != nil {
t.Errorf(`Failed to create the database: %v`, err)
}
for i := range parameters {
new_poll, err := GetAndCreatePollByQuestion(parameters[i].question)
if err != nil {
t.Errorf(`Failed to create new poll %s: %v`, parameters[i].question, err)
}
if new_poll == nil {
t.Errorf(`Failed to insert %s into table`, parameters[i].question)
}
if new_poll.ID != parameters[i].table_index {
t.Errorf(`Incorrect increment in index for %s: expected %d != %d`, parameters[i].question, parameters[i].table_index, new_poll.ID)
}
if new_poll.Question != parameters[i].question {
t.Errorf(`Incorrect question returned: Expected %s != %s`, parameters[i].question, new_poll.Question)
}
}
}
func TestSetVote(t *testing.T) {
// Preload the database with members, polls, and voters
tmp_db, err := os.CreateTemp("", "vote_test.*.db")
if err != nil {
t.Errorf("Failed to create temporary database: %v", err)
}
defer os.Remove(tmp_db.Name())
init_conf := &config.Config{
DBPath: string(tmp_db.Name()),
}
config.SetConfig(init_conf)
err = PreLoadDB()
if err != nil {
t.Errorf("Failed to preload database: %v", err)
}
// Add a non-member vote
random_email := RandString(10) + "@mail.me"
vote := &models.Vote{
PollId: 1,
Email: random_email,
Vote: true,
}
err = SetVote(vote)
if err != nil {
t.Errorf("Failed to set non-member vote: %v", err)
}
// Add a member vote
member_email := "test100@mail.me"
vote = &models.Vote{
PollId: 1,
Email: member_email,
Vote: true,
}
err = SetVote(vote)
if err != nil {
t.Errorf("Failed to set member vote: %v", err)
}
// Verify the votes were added correctly
voters, err := models.GetVoters(1) // Use GetVoters from models
if err != nil {
t.Errorf("Failed to get voters: %v", err)
}
expected_non_member_votes := 4 + 1 // Original non-member votes + new non-member vote
expected_member_votes := 3 + 1 // Original member votes + new member vote
for _, voter := range voters {
if voter.Email == random_email && voter.YesVote {
expected_non_member_votes--
} else if voter.Email == member_email && voter.YesVote {
expected_member_votes--
}
}
if expected_non_member_votes != 5 || expected_member_votes != 4 {
t.Errorf("Expected %d non-member votes and %d member votes, but got %d non-member votes and %d member votes", 4+1, 3+1, expected_non_member_votes, expected_member_votes)
}
}
func TestVoterAlreadyVoted(t *testing.T) {
// Preload the database with members, polls, and voters
tmp_db, err := os.CreateTemp("", "vote_test.*.db")
if err != nil {
t.Errorf("Failed to create temporary database: %v", err)
}
defer os.Remove(tmp_db.Name())
init_conf := &config.Config{
DBPath: string(tmp_db.Name()),
}
config.SetConfig(init_conf)
err = PreLoadDB()
if err != nil {
t.Errorf("Failed to preload database: %v", err)
}
// Add a non-member vote
random_email := RandString(10) + "@mail.me"
vote := &models.Vote{
PollId: 1,
Email: random_email,
Vote: true,
}
err = SetVote(vote)
if err != nil {
t.Errorf("Failed to set non-member vote: %v", err)
}
// Add a member vote
member_email := "test100@mail.me"
vote = &models.Vote{
PollId: 1,
Email: member_email,
Vote: true,
}
err = SetVote(vote)
if err != nil {
t.Errorf("Failed to set member vote: %v", err)
}
// Attempt to add another non-member vote
vote = &models.Vote{
PollId: 1,
Email: random_email,
Vote: true,
}
err = SetVote(vote)
if err != ErrVoterAlreadyVoted {
t.Errorf("Expected ErrVoterAlreadyVoted, but got %v", err)
}
// Attempt to add another member vote
vote = &models.Vote{
PollId: 1,
Email: member_email,
Vote: true,
}
err = SetVote(vote)
if err != ErrVoterAlreadyVoted {
t.Errorf("Expected ErrVoterAlreadyVoted, but got %v", err)
}
}
func TestDeletePollByQuestion(t *testing.T) {
// Preload the database with members, polls, and voters
tmp_db, err := os.CreateTemp("", "vote_test.*.db")
if err != nil {
t.Errorf("Failed to create temporary database: %v", err)
}
defer os.Remove(tmp_db.Name())
init_conf := &config.Config{
DBPath: string(tmp_db.Name()),
}
config.SetConfig(init_conf)
err = PreLoadDB()
if err != nil {
t.Errorf("Failed to preload database: %v", err)
}
// Get a question from the new_polls array
testQuestion := new_polls[0].question
// Delete the poll by question
err = DeletePollByQuestion(testQuestion)
if err != nil {
t.Errorf("Failed to delete poll by question: %v", err)
}
// Verify that the poll was deleted
_, err = GetPollByQuestion(testQuestion)
if err == nil {
t.Errorf("Expected error when getting deleted poll, but got none")
} else if err != ErrPollNotFound {
t.Errorf("Expected ErrPollNotFound, but got %v", err)
}
}