Skip to content

Commit

Permalink
added some pages and archive functionality to some modules
Browse files Browse the repository at this point in the history
  • Loading branch information
HrxSrv committed Dec 23, 2024
1 parent 55ba8dc commit 5ffcb90
Show file tree
Hide file tree
Showing 24 changed files with 528 additions and 129 deletions.
2 changes: 1 addition & 1 deletion src/components/AboutAndVisitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ const IITDelhiInfoCards = () => {

return (
<div className="bg-white ">
<div className="max-w-7xl mx-auto">
<div className="max-w-[80vw] mx-auto">
<div className="flex flex-col md:flex-row gap-8">
{dummyData.map((card, index) =>
card.isDirector ? (
Expand Down
3 changes: 2 additions & 1 deletion src/components/AchievementsSlider.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@ const AchievementsCarousel = () => {
const [startX, setStartX] = useState(0);
const [scrollLeft, setScrollLeft] = useState(0);
const [loading,setLoading] = useState(null);
const [activeTab, setActiveTab] = useState('current');
// Fetch news data using Axios
useEffect(() => {
const fetchNews = async () => {
try {
setLoading(true);
const response = await axiosInstance.get('/achievements/achievements'); // Fetching news data
const response = await axiosInstance.get('/achievements/achievements', { params: { type: activeTab } }); // Fetching news data
const newsItems = response.data.map(item => ({
...item,
imagePublicId: item.image_url, // Assume the API returns 'image' as publicId
Expand Down
2 changes: 1 addition & 1 deletion src/components/FocusOn.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function FocusOn() {
];
return (
<div className="space-y-8 p-4 flex flex-col item-center">
<div className="flex items-center justify-between mb-6 max-width-100 ml-auto mr-auto ">
<div className="flex items-center justify-between mb-6 max-w-[80vw] ml-auto mr-auto ">
<div className="flex items-center">
<div className="flex flex-col w-full text-left">
<h1 className="sm:text-3xl text-2xl font-medium title-font text-gray-900">
Expand Down
158 changes: 117 additions & 41 deletions src/components/ImportantAnnouncement.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import React, { useState, useEffect } from "react";
import React, { useState } from "react";
import {
AlertCircle,
ExternalLink,
RefreshCw,
Bell
Bell,
X,
} from "lucide-react";
import axiosInstance from "../axios";

import { Link } from "react-router-dom";
const AnnouncementSkeleton = () => (
<div className="animate-pulse bg-red-50 py-3 px-4 rounded-lg">
<div className="flex items-center justify-between">
Expand All @@ -16,7 +17,41 @@ const AnnouncementSkeleton = () => (
</div>
);

const Announcement = ({ text, link, createdAt }) => {
function Modal({ isOpen, onClose, children }) {
return (
// backdrop
<div
onClick={onClose}
className={`
fixed inset-0 flex justify-center items-center transition-opacity z-50
${isOpen ? "visible bg-black/20 opacity-100" : "invisible opacity-0"}
`}
>
{/* modal */}
<div
onClick={(e) => e.stopPropagation()}
className={`
fixed bg-white rounded-xl shadow p-6 transition-transform
${isOpen ? "scale-100 opacity-100" : "scale-125 opacity-0"}
`}
style={{
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
}}
>
<button
onClick={onClose}
className="absolute top-2 right-2 p-1 rounded-lg text-gray-400 bg-white hover:bg-gray-50 hover:text-gray-600"
>
<X />
</button>
{children}
</div>
</div>
);
}
const Announcement = ({ text, link, createdAt, isInModal = false }) => {
const formatTimeAgo = (dateString) => {
const date = new Date(dateString);
const now = new Date();
Expand All @@ -30,35 +65,40 @@ const Announcement = ({ text, link, createdAt }) => {

return (
<a
href={link}
className="block w-full bg-gradient-to-r from-red-50 to-red-100 hover:from-red-100 hover:to-red-200 transition-all duration-300 py-4 px-5 rounded-lg group shadow-sm hover:shadow-md border-red-500 h-full"
target="_blank"
rel="noopener noreferrer"
>
<div className="h-full flex flex-col justify-between">
<div className="flex items-center space-x-3 mb-2">
<Bell className="w-5 h-5 text-red-600 animate-pulse" />
<span className="text-red-800 font-semibold text-sm sm:text-base">
{text}
</span>
</div>
<div className="flex items-center justify-between mt-auto">
<span className="text-red-500 text-xs">
{formatTimeAgo(createdAt)}
</span>
<ExternalLink
className="w-5 h-5 text-red-600 group-hover:translate-x-0.5 transition-transform"
/>
href={link}
className={`block transition-all duration-300 rounded-lg group ${
isInModal
? 'bg-white hover:bg-gray-50 shadow-sm hover:shadow p-6 mb-4'
: 'bg-gradient-to-r from-red-50 to-red-100 hover:from-red-100 hover:to-red-200 p-4'
}`}
target="_blank"
rel="noopener noreferrer"
>
<div className="flex flex-col justify-between h-full">
<div className="flex items-start space-x-3">
<Bell className="w-5 h-5 text-red-600 flex-shrink-0 mt-1" />
<span className={`text-red-800 font-medium ${isInModal ? 'text-base' : 'text-sm line-clamp-2'}`}>
{text}
</span>
</div>
<div className="flex items-center justify-between mt-4">
<span className="text-red-500 text-xs">
{formatTimeAgo(createdAt)}
</span>
<ExternalLink
className="w-5 h-5 text-red-600 group-hover:translate-x-0.5 transition-transform"
/>
</div>
</div>
</div>
</a>
);
</a>
);
};

const ImportantAnnouncement = () => {
const [data, setData] = useState([]);
const [error, setError] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [isModalOpen, setIsModalOpen] = useState(false);

const fetchData = async (showLoading = true) => {
if (showLoading) setIsLoading(true);
Expand All @@ -78,15 +118,15 @@ const ImportantAnnouncement = () => {
}
};

useEffect(() => {
React.useEffect(() => {
fetchData();
}, []);

const renderContent = () => {
if (isLoading) {
return (
<div className="space-y-2">
{[1, 2, 3].map((_, index) => (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
{[1, 2, 3, 4].map((_, index) => (
<AnnouncementSkeleton key={index} />
))}
</div>
Expand All @@ -106,7 +146,7 @@ const ImportantAnnouncement = () => {
onClick={() => fetchData()}
className="bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition-colors flex items-center mx-auto"
>
<RefreshCw className="mr-2" /> Retry
<RefreshCw className="mr-2 w-4 h-4" /> Retry
</button>
</div>
);
Expand All @@ -126,22 +166,58 @@ const ImportantAnnouncement = () => {
);
}

const displayedAnnouncements = data.slice(0, 4);
const hasMoreAnnouncements = data.length > 4;

return (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5">
{data.map(({ title, link, createdAt }, index) => (
<Announcement
key={index}
text={title}
link={link}
createdAt={createdAt}
/>
))}
</div>
<>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
{displayedAnnouncements.map(({ title, link, createdAt }, index) => (
<Announcement
key={index}
text={title}
link={link}
createdAt={createdAt}
/>
))}
</div>

{hasMoreAnnouncements && (
<Link
to='/allImportantAnnouncements'
className="mt-6 mx-auto block bg-red-100 text-red-600 px-6 py-2 rounded-full hover:bg-red-200 transition-colors font-medium w-[20vw]"
>
See All Announcements
</Link>
)}

<Modal
isOpen={isModalOpen}
onClose={() => setIsModalOpen(false)}
>
<div className="p-6">
<h2 className="text-2xl font-bold text-gray-900 mb-6">
All Announcements
</h2>
<div className="space-y-4">
{data.map(({ title, link, createdAt }, index) => (
<Announcement
key={index}
text={title}
link={link}
createdAt={createdAt}
isInModal={true}
/>
))}
</div>
</div>
</Modal>
</>
);
};

return (
<div className="w-full max-w-4xl mx-auto">
<div className="w-full max-w-6xl mx-auto px-4">
{renderContent()}
</div>
);
Expand Down
4 changes: 2 additions & 2 deletions src/components/NewsSlider/NewsSlider.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const NewsCarousel = () => {
const [startX, setStartX] = useState(0);
const [scrollLeft, setScrollLeft] = useState(0);
const [isPaused, setIsPaused] = useState(false);

const [activeTab, setActiveTab] = useState('current');
// Auto-scroll functionality
useEffect(() => {
const scrollInterval = setInterval(() => {
Expand All @@ -77,7 +77,7 @@ const NewsCarousel = () => {
const fetchNews = async () => {
try {
setLoading(true)
const response = await axiosInstance.get('/news/news');
const response = await axiosInstance.get('/news/news', { params: { type: activeTab } });
const newsItems = response.data.map(item => ({
...item,
imagePublicId: item.image_url,
Expand Down
4 changes: 2 additions & 2 deletions src/components/Notices.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ const Notices = () => {
const [notices, setNotices] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

const [activeTab, setActiveTab] = useState('current');
useEffect(() => {
const fetchNotices = async () => {
try {
const response = await axiosInstance.get('/notices/notices');
const response = await axiosInstance.get(`/notices/notices`, { params: { type: activeTab } });
setNotices(response.data);
setLoading(false);
} catch (err) {
Expand Down
37 changes: 29 additions & 8 deletions src/data/controllers/AchievementsController.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,34 @@ const Achievements = require('../modals/achievementsModal');
// Get all achievements in descending order of createdAt
exports.getAllAchievements = async (req, res) => {
try {
const achievementsList = await Achievements.findAll({
order: [['createdAt', 'DESC']] // Sort by createdAt in descending order
const { type } = req.query;
let whereClause = {};
if (type === 'current') {
whereClause = {
status: 'ACTIVE'
};
} else if (type === 'archived') {
whereClause = {
status: 'ARCHIVED'
};
}
else {
whereClause= null;
}

const achievements = await Achievements.findAll({
where: whereClause,
order: [['createdAt', 'DESC']]
});
res.json(achievementsList);

res.json(achievements);
} catch (error) {
res.status(500).send(error.message);
console.error('Error fetching achievements:', error);
res.status(500).json({ error: 'Internal server error' });
}
};


// Get achievements overview (limited fields) in descending order of createdAt
exports.getAchievementsOverview = async (req, res) => {
try {
Expand Down Expand Up @@ -44,8 +63,8 @@ exports.getAchievementById = async (req, res) => {
// Create new news
exports.createAchievements = async (req, res) => {
try {
const { title, excerpt, content, image_url, link } = req.body;
if (!title || !link) {
const { title, excerpt, content, image_url, link,status } = req.body;
if (!title || !link || !status) {
return res.status(400).json({
error: 'Required fields missing. Title and link are required.'
});
Expand All @@ -55,7 +74,8 @@ exports.createAchievements = async (req, res) => {
excerpt,
content,
image_url,
link
link,
status
});

res.status(201).json(newNews);
Expand All @@ -68,7 +88,7 @@ exports.createAchievements = async (req, res) => {
exports.updateAchievements = async (req, res) => {
try {
const newsId = req.params.id;
const { title, excerpt, content, image_url, link } = req.body;
const { title, excerpt, content, image_url, link, status } = req.body;

const news = await Achievements.findByPk(newsId);

Expand All @@ -85,6 +105,7 @@ exports.updateAchievements = async (req, res) => {
if (content !== undefined) updates.content = content;
if (image_url !== undefined) updates.image_url = image_url;
if (link !== undefined) updates.link = link;
if (status !== undefined) updates.status = status;

await news.update(updates);

Expand Down
Loading

0 comments on commit 5ffcb90

Please sign in to comment.