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
7 changes: 4 additions & 3 deletions frontend/src/Components/Feedback/FeedbackForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { useFeedbackForm } from "../../hooks/useFeedback";
const FeedbackForm = () => {
const { formData, filteredTargets, updateFormData, submitFeedback } =
useFeedbackForm();

const feedbackTypes = [
"Suggestion",
"Complaint",
Expand Down Expand Up @@ -117,8 +116,10 @@ const FeedbackForm = () => {
<Select
options={filteredTargets}
value={
filteredTargets.find((option) => option.value === formData.target_id) || null
}
filteredTargets.find(
(option) => option.value === formData.target_id,
) || null
}
onChange={handleTargetChange}
isClearable
placeholder="Select target"
Expand Down
79 changes: 77 additions & 2 deletions frontend/src/Components/Feedback/FeedbackStats.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,82 @@
import React from "react";

import { useState, useContext } from "react";
import { AdminContext } from "../../context/AdminContext";
import { useFeedback } from "../../hooks/useFeedback";
import getCurrentTenureRange from "../../utils/getCurrentTenureRange";
const FeedbackStats = () => {
return <div>FeedbackStats</div>;
const {
loading,
activeTab,
setActiveTab,
statusFilter,
setStatusFilter,
filteredFeedbacks,
markAsResolved,
} = useFeedback();
const { startDate, endDate, tenureYearString } = getCurrentTenureRange();
const tenureFeedback = filteredFeedbacks.filter((fb) => {
const createdAt = new Date(fb.created_at);
return createdAt >= startDate && createdAt <= endDate;
});
const { isUserLoggedIn } = useContext(AdminContext);
const isStudent = isUserLoggedIn?.role === "STUDENT";

return (
<div className="p-2 flex flex-col items-center justify-center">
<p className="text-xl font-semibold justify-center">Feedback Stats</p>
<p className="text-gray-800 mb-2 ">
Total feedbacks:{" "}
<span className="font-semibold text-blue-600">
{tenureFeedback.length}
</span>
</p>

<p className="text-gray-800 mb-2">
Pending feedbacks:{" "}
<span className="font-semibold text-yellow-600">
{tenureFeedback.filter((fb) => !fb.is_resolved).length}
</span>
</p>

<p className="text-gray-800 mb-2 ">
Total resolved feedbacks:{" "}
<span className="font-semibold text-green-600">
{tenureFeedback.filter((fb) => fb.is_resolved).length}
</span>
</p>

<p className="text-gray-800 mb-2">
Recent feedbacks:{" "}
<span className="font-semibold text-purple-600">
{
tenureFeedback.filter((fb) => {
const now = new Date();
const thirtyDaysAgo = new Date();
thirtyDaysAgo.setDate(now.getDate() - 30);
// Clamp to tenure start boundary
const effectiveStart =
thirtyDaysAgo < startDate ? startDate : thirtyDaysAgo;
const createdAt = new Date(fb.created_at);
return createdAt >= effectiveStart && createdAt <= now;
}).length
}
</span>
</p>
<p className="text-gray-800 mb-2">
Average Rating:{" "}
<span className="font-bold">
{tenureFeedback.filter((fb) => fb.rating).length > 0
? (
tenureFeedback.reduce(
(sum, fb) => (fb.rating ? sum + fb.rating : sum),
0,
) / tenureFeedback.filter((fb) => fb.rating).length
).toFixed(1)
: 0}
</span>
</p>
</div>
);
};

export default FeedbackStats;
27 changes: 14 additions & 13 deletions frontend/src/hooks/useFeedback.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,22 @@ export const useFeedback = () => {
const [statusFilter, setStatusFilter] = useState("All");
const { isUserLoggedIn } = useContext(AdminContext);

const fetchFeedback = async () => {
try {
const res = await api.get(`/api/feedback/view-feedback`);
const sorted = res.data.sort(
(a, b) => new Date(b.created_at) - new Date(a.created_at),
);
setFeedbacks(sorted);
} catch (error) {
console.error("Error fetching feedbacks:", error);
} finally {
setLoading(false);
}
};

// Fetch feedbacks
useEffect(() => {
const fetchFeedback = async () => {
try {
const res = await api.get(`/api/feedback/view-feedback`);
const sorted = res.data.sort(
(a, b) => new Date(b.created_at) - new Date(a.created_at),
);
setFeedbacks(sorted);
} catch (error) {
console.error("Error fetching feedbacks:", error);
} finally {
setLoading(false);
}
};
fetchFeedback();
}, []);

Expand Down
19 changes: 19 additions & 0 deletions frontend/src/utils/getCurrentTenureRange.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const getCurrentTenureRange = () => {
const now = new Date();
const current_year = now.getFullYear();
const current_month = now.getMonth(); // months are 0-indexed

let startDate, endDate, tenureYearString;
if (current_month < 3) {
startDate = new Date(current_year - 1, 3, 1);
endDate = new Date(current_year, 2, 31, 23, 59, 59);
tenureYearString = `${current_year - 1}-${current_year}`;
} else {
startDate = new Date(current_year, 3, 1);
endDate = new Date(current_year + 1, 2, 31, 23, 59, 59);
tenureYearString = `${current_year}-${current_year + 1}`;
}
return { startDate, endDate, tenureYearString };
};

module.exports = getCurrentTenureRange;