Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/MeetDOD/StyleShare into iss…
Browse files Browse the repository at this point in the history
…ue-576
  • Loading branch information
MeetDOD committed Aug 8, 2024
2 parents eb045d4 + fbbde94 commit bf4a817
Show file tree
Hide file tree
Showing 16 changed files with 353 additions and 128 deletions.
7 changes: 7 additions & 0 deletions admin/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM node:alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
EXPOSE 5173
CMD ["npm", "run" , "dev"]
24 changes: 23 additions & 1 deletion admin/src/pages/ContactMessages.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import '../styles/Model.css'
import { ColorRing } from 'react-loader-spinner';
import { MdMessage } from "react-icons/md";
import { TbReportAnalytics } from "react-icons/tb";
import toast from "react-hot-toast";

const ContactMessages = () => {
const [contactMessages, setContactMessages] = useState<IContactMessage[]>([]);
Expand Down Expand Up @@ -59,6 +60,21 @@ const ContactMessages = () => {
}
};

const handleDeleteMessage = async (id: string) => {
try {
await axios.delete(`/api/v1/admin/deletecontactmessage/${id}`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
setContactMessages(contactMessages.filter((msg) => msg.id !== id));
toast.success("Contact Message deleted successfully !")
} catch (error) {
console.error("Error deleting message:", error);
toast.error("Error in deleting message")
}
};

const handleOpenModal = (message: IContactMessage) => {
setSelectedMessage(message);
setOpen(true);
Expand Down Expand Up @@ -114,7 +130,7 @@ const ContactMessages = () => {
<td className="px-8 py-4 font-semibold">{new Date(contactMessage.createdAt).toLocaleDateString()}</td>
<td className="px-8 py-4 font-semibold">{contactMessage.subject.slice(0, 10)}</td>
<td className="px-12 py-4 font-semibold">{contactMessage.message.slice(0, 10)}</td>
<td className="px-2 py-4 grid grid-cols-1 gap-3 justify-center md:grid-cols-2">
<td className="px-2 py-4 grid grid-cols-1 gap-3 justify-center md:grid-cols-3">
<button
onClick={() => handleOpenModal(contactMessage)}
className="font-semibold rounded-md p-2 bg-sky-500 text-white border-2 hover:bg-sky-600"
Expand All @@ -129,6 +145,12 @@ const ContactMessages = () => {
>
Reply
</a>
<button
onClick={() => handleDeleteMessage(contactMessage.id)}
className="font-semibold rounded-md p-2 bg-red-500 text-white border-2 hover:bg-red-600"
>
Delete
</button>
</td>
</tr>
))}
Expand Down
10 changes: 10 additions & 0 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM node:alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm run backend-build


EXPOSE 8000
CMD ["npm", "run" , "dev"]
19 changes: 19 additions & 0 deletions backend/src/routes/admin/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1090,6 +1090,25 @@ export const downloadFavoritesReportController = async (req: Request, res: Respo
}
};

export const deleteContactMessage = async (req: Request, res: Response) => {
const { id } = req.params;

try {
const deletedMessage = await prisma.contactMessage.delete({
where: { id },
});

res.status(200).json({
message: "Contact message deleted successfully!",
deletedMessage,
});
} catch (error) {
res.status(500).json({
error: "An error occurred while deleting the contact message!",
});
}
};

export const deleteFeedback = async (req: Request, res: Response) => {
const { id } = req.params;

Expand Down
4 changes: 3 additions & 1 deletion backend/src/routes/admin/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Router} from 'express';
import { getPostReactionsController,getFavoritesController,adminLoginController, adminProfileController, allUserForAdmin, blockUserController, unblockUserController, getAdminPostsController, getAdminTrendingPostsController, getAdminStatsController, getGraphsStatsController, updatePostController, deletePostController, getPostByIdController, getAllContactMessages, deleteCommentController, downloadReportController, getFeedbacks, toggleFeedbackVisibility, downloadCommentsReportController, downloadFavoritesReportController, downloadReactionsReportController, downloadUsersReportController, downloadContactMessagesReportController, downloadPostsReportController, deleteFeedback } from './controller';
import { getPostReactionsController,getFavoritesController,adminLoginController, adminProfileController, allUserForAdmin, blockUserController, unblockUserController, getAdminPostsController, getAdminTrendingPostsController, getAdminStatsController, getGraphsStatsController, updatePostController, deletePostController, getPostByIdController, getAllContactMessages, deleteCommentController, downloadReportController, getFeedbacks, toggleFeedbackVisibility, downloadCommentsReportController, downloadFavoritesReportController, downloadReactionsReportController, downloadUsersReportController, downloadContactMessagesReportController, downloadPostsReportController, deleteContactMessage, deleteFeedback } from './controller';
import { isAdmin } from '../../middleware/adminAuth';

const adminRouter = Router();
Expand Down Expand Up @@ -54,6 +54,8 @@ adminRouter.get("/downloadusersfavoritesreport", downloadFavoritesReportControll

adminRouter.get("/downloadusersreactionreport", downloadReactionsReportController);

adminRouter.delete("/deletecontactmessage/:id", isAdmin, deleteContactMessage);

adminRouter.delete('/deletefeedback/:id', isAdmin, deleteFeedback);

export default adminRouter;
40 changes: 40 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

services:

admin:
build:
context: ./admin
container_name: styleshare-admin
ports:
- '5173:5173'

frontend:
build:
context: ./frontend
container_name: styleshare-frontend
ports:
- '3000:3000'

backend:
build:
context: ./backend
container_name: styleshare-backend
depends_on:
- db
environment:
- DATABASE_URL=${DATABASE_URL}

ports:
- '8000:8000'

db:
image: mongo:latest
container_name: styleshare-db
restart: always
ports:
- '27017:27017'
volumes:
- mongodb_data:/data/db

volumes:
mongodb_data:
7 changes: 7 additions & 0 deletions frontend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM node:alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "run" , "dev"]
9 changes: 9 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"react-fast-marquee": "^1.6.4",
"react-hot-toast": "^2.4.1",
"react-icons": "^5.2.1",
"react-loading-skeleton": "^3.4.0",
"react-parallax-tilt": "^1.7.231",
"react-responsive-modal": "^6.4.2",
"react-router-dom": "^6.24.0",
Expand Down
59 changes: 59 additions & 0 deletions frontend/src/components/LeaderboardSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import Skeleton from 'react-loading-skeleton';
import 'react-loading-skeleton/dist/skeleton.css';

const LeaderboardSkeleton = () => {
const skeletonArray = Array(5).fill(0); // Adjust the number of skeleton rows as needed

return (
<div className="overflow-x-auto">
<table className="min-w-full divide-y divide-gray-200">
<thead className="text-center text-sm font-medium text-[#000435] bg-white dark:text-white dark:bg-[#5f67de] border-b-2 border-sky-600">
<tr>
<th scope="col" className="px-2 py-3 sm:px-6 text-[#5f67de] bg-white dark:text-white dark:bg-[#000435] uppercase tracking-wider">
<Skeleton width={60} height={20} className=" rounded dark:bg-white" />
</th>
<th scope="col" className="px-2 py-3 sm:px-6 text-[#5f67de] bg-white dark:text-white dark:bg-[#000435] uppercase tracking-wider">
<Skeleton width={80} height={20} className=" rounded dark:bg-white" />
</th>
<th scope="col" className="px-2 py-3 sm:px-6 mx-12 text-[#5f67de] bg-white dark:text-white dark:bg-[#000435] uppercase tracking-wider">
<Skeleton width={120} height={20} className=" rounded dark:bg-white" />
</th>
<th scope="col" className="px-2 py-3 sm:px-6 text-[#5f67de] bg-white dark:text-white dark:bg-[#000435] uppercase tracking-wider">
<Skeleton width={60} height={20} className=" rounded dark:bg-white" />
</th>
<th scope="col" className="px-2 py-3 sm:px-6 text-[#5f67de] bg-white dark:text-white dark:bg-[#000435] uppercase tracking-wider">
<Skeleton width={60} height={20} className=" rounded dark:bg-white" />
</th>
</tr>
</thead>
<tbody>
{skeletonArray.map((_, index) => (
<tr key={index} className="text-center text-[#000435] dark:text-gray-50 border-b-2 border-sky-900">
<td className="px-2 py-4 sm:px-6">
<div className="flex flex-col items-center">
<Skeleton width={40} height={40} circle={true} className=" rounded-full dark:bg-white" />
</div>
</td>
<td className="px-2 py-4 sm:px-6">
<div className="flex flex-col items-center">
<Skeleton width={40} height={40} circle={true} className=" rounded-full dark:bg-white" />
</div>
</td>
<td className="px-2 py-4 sm:px-6">
<Skeleton width={120} height={20} className=" rounded dark:bg-white" />
</td>
<td className="px-2 py-4 sm:px-6">
<Skeleton width={60} height={20} className=" rounded dark:bg-white" />
</td>
<td className="px-2 py-4 sm:px-6">
<Skeleton width={60} height={20} className=" rounded dark:bg-white" />
</td>
</tr>
))}
</tbody>
</table>
</div>
);
};

export default LeaderboardSkeleton;
Loading

0 comments on commit bf4a817

Please sign in to comment.