Fix the frontend API calls and implement logins on frontend #7

Merged
dylan merged 24 commits from feat/update-frontend-api-calls into main 2026-03-04 20:20:50 +00:00
2 changed files with 35 additions and 13 deletions
Showing only changes of commit 207c4b67da - Show all commits

View File

@@ -7,6 +7,7 @@ const styles = StatsStyling;
const API_BASE_URL = "http://localhost:5000"; const API_BASE_URL = "http://localhost:5000";
const UploadPage = () => { const UploadPage = () => {
const [datasetName, setDatasetName] = useState("");
const [postFile, setPostFile] = useState<File | null>(null); const [postFile, setPostFile] = useState<File | null>(null);
const [topicBucketFile, setTopicBucketFile] = useState<File | null>(null); const [topicBucketFile, setTopicBucketFile] = useState<File | null>(null);
const [returnMessage, setReturnMessage] = useState(""); const [returnMessage, setReturnMessage] = useState("");
@@ -15,6 +16,14 @@ const UploadPage = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const uploadFiles = async () => { const uploadFiles = async () => {
const normalizedDatasetName = datasetName.trim();
if (!normalizedDatasetName) {
setHasError(true);
setReturnMessage("Please add a dataset name before continuing.");
return;
}
if (!postFile || !topicBucketFile) { if (!postFile || !topicBucketFile) {
setHasError(true); setHasError(true);
setReturnMessage("Please upload both files before continuing."); setReturnMessage("Please upload both files before continuing.");
@@ -22,6 +31,7 @@ const UploadPage = () => {
} }
const formData = new FormData(); const formData = new FormData();
formData.append("name", normalizedDatasetName);
formData.append("posts", postFile); formData.append("posts", postFile);
formData.append("topics", topicBucketFile); formData.append("topics", topicBucketFile);
@@ -63,7 +73,7 @@ const UploadPage = () => {
<div> <div>
<h1 style={{ margin: 0, color: "#111827", fontSize: 28 }}>Upload Dataset</h1> <h1 style={{ margin: 0, color: "#111827", fontSize: 28 }}>Upload Dataset</h1>
<p style={{ margin: "8px 0 0", color: "#6b7280", fontSize: 14 }}> <p style={{ margin: "8px 0 0", color: "#6b7280", fontSize: 14 }}>
Add your posts and topic map files to generate fresh analytics. Name your dataset, then upload posts and topic map files to generate analytics.
</p> </p>
</div> </div>
<button <button
@@ -83,11 +93,23 @@ const UploadPage = () => {
gridTemplateColumns: "repeat(auto-fit, minmax(280px, 1fr))", gridTemplateColumns: "repeat(auto-fit, minmax(280px, 1fr))",
}} }}
> >
<div style={{ ...styles.card, gridColumn: "auto" }}>
<h2 style={{ ...styles.sectionTitle, color: "#111827" }}>Dataset Name</h2>
<p style={styles.sectionSubtitle}>Use a clear label so you can identify this upload later.</p>
<input
style={{ ...styles.input, width: "100%", maxWidth: "100%", boxSizing: "border-box" }}
type="text"
placeholder="Example: Cork Discussions - Jan 2026"
value={datasetName}
onChange={(event) => setDatasetName(event.target.value)}
/>
</div>
<div style={{ ...styles.card, gridColumn: "auto" }}> <div style={{ ...styles.card, gridColumn: "auto" }}>
<h2 style={{ ...styles.sectionTitle, color: "#111827" }}>Posts File (.jsonl)</h2> <h2 style={{ ...styles.sectionTitle, color: "#111827" }}>Posts File (.jsonl)</h2>
<p style={styles.sectionSubtitle}>Upload the raw post records export.</p> <p style={styles.sectionSubtitle}>Upload the raw post records export.</p>
<input <input
style={{ ...styles.input, width: "80%", maxWidth: "100%" }} style={{ ...styles.input, width: "100%", maxWidth: "100%", boxSizing: "border-box" }}
type="file" type="file"
accept=".jsonl" accept=".jsonl"
onChange={(event) => setPostFile(event.target.files?.[0] ?? null)} onChange={(event) => setPostFile(event.target.files?.[0] ?? null)}
@@ -101,7 +123,7 @@ const UploadPage = () => {
<h2 style={{ ...styles.sectionTitle, color: "#111827" }}>Topics File (.json)</h2> <h2 style={{ ...styles.sectionTitle, color: "#111827" }}>Topics File (.json)</h2>
<p style={styles.sectionSubtitle}>Upload your topic bucket mapping file.</p> <p style={styles.sectionSubtitle}>Upload your topic bucket mapping file.</p>
<input <input
style={{ ...styles.input, width: "80%", maxWidth: "100%" }} style={{ ...styles.input, width: "100%", maxWidth: "100%", boxSizing: "border-box" }}
type="file" type="file"
accept=".json" accept=".json"
onChange={(event) => setTopicBucketFile(event.target.files?.[0] ?? null)} onChange={(event) => setTopicBucketFile(event.target.files?.[0] ?? null)}

View File

@@ -45,6 +45,7 @@ auth_manager = AuthManager(db, bcrypt)
dataset_manager = DatasetManager(db) dataset_manager = DatasetManager(db)
stat_gen = StatGen() stat_gen = StatGen()
@app.route("/register", methods=["POST"]) @app.route("/register", methods=["POST"])
def register_user(): def register_user():
data = request.get_json() data = request.get_json()
@@ -113,12 +114,15 @@ def get_user_datasets():
@app.route("/upload", methods=["POST"]) @app.route("/upload", methods=["POST"])
@jwt_required() @jwt_required()
def upload_data(): def upload_data():
if "posts" not in request.files or "topics" not in request.files or "name" not in request.form: if "posts" not in request.files or "topics" not in request.files:
return jsonify({"error": "Missing required files or form data"}), 400 return jsonify({"error": "Missing required files or form data"}), 400
post_file = request.files["posts"] post_file = request.files["posts"]
topic_file = request.files["topics"] topic_file = request.files["topics"]
dataset_name = request.form["name"] dataset_name = (request.form.get("name") or "").strip()
if not dataset_name:
return jsonify({"error": "Missing required dataset name"}), 400
if post_file.filename == "" or topic_file.filename == "": if post_file.filename == "" or topic_file.filename == "":
return jsonify({"error": "Empty filename"}), 400 return jsonify({"error": "Empty filename"}), 400
@@ -137,17 +141,13 @@ def upload_data():
topics = json.load(topic_file) topics = json.load(topic_file)
dataset_id = dataset_manager.save_dataset_info(current_user, dataset_name, topics) dataset_id = dataset_manager.save_dataset_info(current_user, dataset_name, topics)
process_dataset.delay( process_dataset.delay(dataset_id, posts_df.to_dict(orient="records"), topics)
dataset_id,
posts_df.to_dict(orient="records"),
topics
)
return jsonify( return jsonify(
{ {
"message": "Dataset queued for processing", "message": "Dataset queued for processing",
"dataset_id": dataset_id, "dataset_id": dataset_id,
"status": "processing" "status": "processing",
} }
), 202 ), 202
except ValueError as e: except ValueError as e: