Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 41 additions & 10 deletions app-backend/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,7 @@ def send_email():
<h1>Hello,</h1>
<p>We received a request to reset your password. If you made this request, please click the link below to reset your password:</p>

<p><a href="https://www.google.com/" class="button">Reset Your Password</a></p>
<p><a href="http://localhost:5173/reset-password" class="button">Reset Your Password</a></p>

<p>If you did not request a password reset, please ignore this email, and your account will remain secure.</p>

Expand Down Expand Up @@ -1015,9 +1015,9 @@ def view_patients(therapist_id):
@app.route('/add_finances', methods=['POST'])
def add_finances():
data = request.get_json()
money = data.get('money')

if not isinstance(money, (int, float)) or money <= 0:
money_str = data.get('money')
money = float(money_str)
if money <= 0:
return jsonify({"error": "Invalid amount. Money must be a positive number."}), 400

finance = db.session.query(Finances).first()
Expand All @@ -1036,10 +1036,13 @@ def add_finances():
@app.route('/add_coupons', methods=['POST'])
def add_coupons():
data = request.get_json()
coupon_id = data.get('coupon_id')
num_coupons = data.get('num_coupons')
coupon_id_str = data.get('coupon_id')
num_coupons_str = data.get('num_coupons')
num_coupons=float(num_coupons_str)
coupon_id=float(coupon_id_str)
print(num_coupons,coupon_id)

if not coupon_id or not isinstance(num_coupons, int) or num_coupons <= 0:
if not coupon_id or num_coupons <= 0:
return jsonify({"error": "Invalid input. 'coupon_id' and 'num_coupons' are required and 'num_coupons' must be a positive integer."}), 400

coupon = db.session.query(Coupon).filter_by(id=coupon_id).first()
Expand All @@ -1058,10 +1061,11 @@ def add_coupons():
def enlist_coupon():
data = request.get_json()
partner_name = data.get('partner_name')
num_coupons = data.get('num_coupons')
num_coupons_str = data.get('num_coupons')
valid_until = data.get('valid_until')

if not partner_name or not isinstance(num_coupons, int) or num_coupons <= 0:
num_coupons=float(num_coupons_str)
print(partner_name,num_coupons,valid_until)
if not partner_name or num_coupons <= 0:
return jsonify({"error": "Invalid input. 'partner_name' is required and 'num_coupons' must be a positive integer."}), 400

if not valid_until:
Expand Down Expand Up @@ -2551,6 +2555,33 @@ def list_badges():

with app.app_context():
db.create_all()
@app.route('/get_user_badges/<int:user_id>', methods=['GET'])
def get_user_badges(user_id):

badges = (
db.session.query(Badge)
.join(UserBadge)
.filter(UserBadge.user_id == user_id)
.all()
)
print("''''''''''''''''''''''''''''''''''''''''''''")
print("''''''''''''''''''''''''''''''''''''''''''''")
print("''''''''''''''''''''''''''''''''''''''''''''")
print("''''''''''''''''''''''''''''''''''''''''''''")

print("''''''''''''''''''''''''''''''''''''''''''''")
print("user_id",badges)
return [
{
"id": badge.id,
"name": badge.name,
"picture": badge.picture
}
for badge in badges
]




if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
Binary file modified app-backend/instance/eunoia.db
Binary file not shown.
6 changes: 3 additions & 3 deletions app-frontend/src/components/admin/ActivityEngagement.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default function ActivityEngagement({ className }) {
<TableCell>Activity Name</TableCell>
<TableCell>Engagement Rate (%)</TableCell>
<TableCell>Completion Rate (%)</TableCell>
<TableCell>Actions</TableCell>
{/* <TableCell>Actions</TableCell> */}
</TableRow>
</TableHeader>
<TableBody>
Expand All @@ -44,15 +44,15 @@ export default function ActivityEngagement({ className }) {
<TableCell>{activity.name}</TableCell>
<TableCell>{activity.engagement}%</TableCell>
<TableCell>{activity.completionRate}%</TableCell>
<TableCell>
{/* <TableCell>
<Button
variant="outline"
size="sm"
className="mr-2 bg-blue-500 text-white"
>
Edit
</Button>
</TableCell>
</TableCell> */}
</TableRow>
))}
</TableBody>
Expand Down
15 changes: 14 additions & 1 deletion app-frontend/src/components/user/EarnedBadges.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React from "react";
import React, { useEffect } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Award } from "lucide-react";
import axios from "axios";
import useStore from "@/useStore";

const badges = [
{ name: "Consistency Champion", description: "7-day streak" },
Expand All @@ -10,6 +12,17 @@ const badges = [
];

export default function EarnedBadges({ className }) {
const user_id = useStore((state) => state.clientId);
useEffect(() => {
axios
.get(`http://localhost:5000/get_user_badges/${user_id}`)
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
});
return (
<Card className={className}>
<CardHeader>
Expand Down
90 changes: 64 additions & 26 deletions app-frontend/src/pages/admin/Finances.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,36 @@ import React, { useState, useEffect } from "react";
import { Helmet } from "react-helmet";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import DashboardHeader from "@/components/admin/DashboardHeader";
import DashboardShell from "@/components/admin/DashboardShell";
import axios from "axios";
import axios from "axios";

export default function Finances() {
const [finances, setFinances] = useState(null);
const [coupons, setCoupons] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [partnerName, setPartnerName] = useState("");
const [numCoupons, setNumCoupons] = useState(0);
const [validUntil, setValidUntil] = useState("");
const [couponId, setCouponId] = useState("");
const [finances, setFinances] = useState(null);
const [coupons, setCoupons] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [partnerName, setPartnerName] = useState("");
const [numCoupons, setNumCoupons] = useState(0);
const [validUntil, setValidUntil] = useState("");
const [couponId, setCouponId] = useState("");
const [addCoupons, setAddCoupons] = useState(0);
const [addAmount, setAddAmount] = useState(0);
const [addAmount, setAddAmount] = useState(0);

const fetchFinances = async () => {
try {
const response = await axios.get("http://localhost:5000/get_finances");
if (response.status === 200) {
setFinances(response.data.finances_available);
setCoupons(response.data.coupons);
setFinances(response.data.finances_available);
setCoupons(response.data.coupons);
}
} catch (err) {
setError("Failed to fetch finance data.");
Expand All @@ -34,13 +41,16 @@ export default function Finances() {
};

useEffect(() => {
fetchFinances();
fetchFinances();
}, []);

if (loading) {
return (
<DashboardShell>
<DashboardHeader heading="Finances" text="Manage and monitor financial data.">
<DashboardHeader
heading="Finances"
text="Manage and monitor financial data."
>
<Button className="bg-blue-500 text-white hover:bg-blue-600">
Add Finance
</Button>
Expand All @@ -55,7 +65,10 @@ export default function Finances() {
if (error) {
return (
<DashboardShell>
<DashboardHeader heading="Finances" text="Manage and monitor financial data.">
<DashboardHeader
heading="Finances"
text="Manage and monitor financial data."
>
<Button className="bg-blue-500 text-white hover:bg-blue-600">
Add Finance
</Button>
Expand All @@ -68,32 +81,41 @@ export default function Finances() {
}

const handleEnlistCoupon = async () => {
console.log(partnerName, numCoupons, validUntil);
try {
const response = await axios.post("http://localhost:5000/enlist_coupon", {
partner_name: partnerName,
num_coupons: numCoupons,
valid_until: validUntil,
});
console.log(response);
if (response.status === 201) {
setCoupons([...coupons, response.data]);
setCoupons([...coupons, response.data]);
alert("Coupon enlisted successfully!");
}
} catch (err) {
setError("Failed to enlist coupon.");
console.log(err);
}
};

const handleAddCoupons = async () => {
console.log(couponId, addCoupons);
try {
const response = await axios.post("http://localhost:5000/add_coupons", {
coupon_id: couponId,
num_coupons: addCoupons,
});
console.log("response outside", response);
if (response.status === 201) {
alert(`Successfully added ${addCoupons} coupons to coupon ID ${couponId}`);
fetchFinances(); }
alert(
`Successfully added ${addCoupons} coupons to coupon ID ${couponId}`
);
fetchFinances();
}
} catch (err) {
setError("Failed to add coupons.");
console.log(err);
}
};

Expand All @@ -102,8 +124,9 @@ export default function Finances() {
const response = await axios.post("http://localhost:5000/add_finances", {
money: addAmount,
});
console.log("response outside", response);
if (response.status === 201) {
setFinances(response.data.current_finances);
setFinances(response.data.current_finances);
alert(`Successfully added $${addAmount} to finances.`);
}
} catch (err) {
Expand All @@ -118,10 +141,16 @@ export default function Finances() {
<meta name="description" content="Manage and monitor financial data." />
</Helmet>
<DashboardShell>
<DashboardHeader heading="Finances" text="Manage and monitor financial data.">
<Button onClick={() => {}} className="bg-blue-500 text-white hover:bg-blue-600">
<DashboardHeader
heading="Finances"
text="Manage and monitor financial data."
>
{/* <Button
onClick={() => {}}
className="bg-blue-500 text-white hover:bg-blue-600"
>
Add Finance
</Button>
</Button> */}
</DashboardHeader>

<div className="grid gap-6">
Expand All @@ -142,7 +171,10 @@ export default function Finances() {
className="border px-3 py-2 rounded-md w-full"
placeholder="Amount to add to finances"
/>
<Button onClick={handleAddFinances} className="mt-2 bg-green-500 text-white hover:bg-green-600">
<Button
onClick={handleAddFinances}
className="mt-2 bg-green-500 text-white hover:bg-green-600"
>
Add to Finances
</Button>
</div>
Expand Down Expand Up @@ -188,7 +220,10 @@ export default function Finances() {
onChange={(e) => setAddCoupons(e.target.value)}
className="border px-3 py-2 rounded-md w-full mt-2"
/>
<Button onClick={handleAddCoupons} className="mt-2 bg-blue-500 text-white hover:bg-blue-600">
<Button
onClick={handleAddCoupons}
className="mt-2 bg-blue-500 text-white hover:bg-blue-600"
>
Add Coupons
</Button>
</div>
Expand All @@ -214,7 +249,10 @@ export default function Finances() {
onChange={(e) => setValidUntil(e.target.value)}
className="border px-3 py-2 rounded-md w-full mt-2"
/>
<Button onClick={handleEnlistCoupon} className="mt-2 bg-green-500 text-white hover:bg-green-600">
<Button
onClick={handleEnlistCoupon}
className="mt-2 bg-green-500 text-white hover:bg-green-600"
>
Enlist Coupon
</Button>
</div>
Expand Down
Loading