Merge branch 'main' into production

This commit is contained in:
Dobromir Popov
2024-03-05 16:53:27 +02:00
7 changed files with 82 additions and 47 deletions

View File

@ -11,5 +11,5 @@ TELEGRAM_BOT=true
SSL_KEY=./certificates/localhost-key.pem
SSL_CERT=./certificates/localhost.pem
# DATABASE_URL=mysql://root:Zelen0ku4e@192.168.0.10:3306/cart_dev
DATABASE_URL=mysql://cart:cartpw@localhost:3306/cart
DATABASE_URL=mysql://root:Zelen0ku4e@192.168.0.10:3306/cart_dev
# DATABASE_URL=mysql://cart:cartpw@localhost:3306/cart

View File

@ -109,7 +109,7 @@ next start
export OPENAI_API_KEY=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 # personal
export OPENAI_API_KEY=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 # dev-bro
# -------------update PRISMA schema/sync database ------------------------ #
# ----------------------------------------------update PRISMA schema/sync database ----------------------------------------------- #
# prisma migrate dev --create-only
npx prisma generate
npx prisma migrate dev --name fix_nextauth_schema --create-only

View File

@ -56,30 +56,27 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o
}, []);
// Define the minimum and maximum times
const minTime = new Date();
minTime.setHours(8, 0, 0, 0); // 8:00 AM
const maxTime = new Date();
maxTime.setHours(20, 0, 0, 0); // 8:00 PM
const fetchItemFromDB = async () => {
const id = parseInt(router.query.id);
if (existingItems.length == 0 && id) {
try {
const response = await axiosInstance.get(`/api/data/availabilities/${id}`);
setAvailabilities([response.data]);
setEditMode(true);
} catch (error) {
console.error(error);
toast.error("Error fetching availability data.");
}
}
};
useEffect(() => {
const fetchItemFromDB = async () => {
const id = parseInt(router.query.id);
if (existingItems.length == 0 && id) {
try {
const response = await axiosInstance.get(`/api/data/availabilities/${id}`);
setAvailabilities([response.data]);
setEditMode(true);
} catch (error) {
console.error(error);
toast.error("Error fetching availability data.");
}
}
};
fetchItemFromDB();
}, [router.query.id]);
@ -193,6 +190,7 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o
repeatWeekly: doRepeat,
dayOfMonth: doRepeat ? null : startTime.getDate(),
endDate: doRepeat ? repeatUntil : null,
dateOfEntry: new Date(),
};
}
@ -207,13 +205,10 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o
availability.repeatWeekly = doRepeat;
availability.dayOfMonth = doRepeat ? null : availability.startTime.getDate();
availability.endDate = doRepeat ? repeatUntil : null;
availability.dateOfEntry = new Date();
return availability;
}
const handleDelete = async (e) => {
e.preventDefault();
try {
@ -231,9 +226,10 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o
handleCompletion({ deleted: true });
}
} catch (error) {
alert("Нещо се обърка при изтриването. Моля, опитайте отново или се свържете с нас");
//alert("Нещо се обърка при изтриването. Моля, опитайте отново или се свържете с нас");
console.log(JSON.stringify(error));
toast.error(error.response?.data?.message || "An error occurred");
fetchItemFromDB();
}
};

View File

@ -1,4 +1,4 @@
import React, { useState } from "react";
import React, { useState, useEffect } from "react";
import toast from "react-hot-toast";
import { useRouter } from "next/router";
import Link from "next/link";

View File

@ -6,28 +6,64 @@ import axiosServer from '../../../src/axiosServer';
import common from '../../../src/helpers/common';
import ShiftsList from '../../../components/publisher/ShiftsList';
import { monthNamesBG, GetTimeFormat, GetDateFormat } from "../../../src/helpers/const"
import { useSession, getSession } from 'next-auth/react';
export default function MySchedulePage({ assignments }) {
const { data: session, status } = useSession();
if (status === "loading") {
return <div>Loading...</div>;
return <div className="flex justify-center items-center h-screen">Loading...</div>;
}
return (
<Layout>
<ProtectedRoute allowedRoles={[UserRole.ADMIN, UserRole.POWERUSER, UserRole.USER]}>
<div className="container mx-auto p-4">
<h1 className="text-xl font-semibold mb-4">Моите смени</h1>
<ShiftsList assignments={assignments} selectedtab={common.getCurrentYearMonth()} />
<h1 className="text-2xl md:text-3xl font-bold text-center my-4">Моите смени</h1>
<div className="space-y-4">
{assignments && assignments.map((assignment) => (
<div key={assignment.dateStr} className="bg-white shadow overflow-hidden rounded-lg">
<div className="px-4 py-5 sm:px-6">
<h3 className="text-lg leading-6 font-medium text-gray-900">{assignment.dateStr}</h3>
</div>
<div className="border-t border-gray-200">
<dl>
<div className="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500">Час</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
{GetTimeFormat(assignment.shift.startTime)} - {GetTimeFormat(assignment.shift.endTime)}
</dd>
</div>
<div className="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500">Действия</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
<button
className="mr-2 mb-2 inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md shadow-sm text-white bg-green-600 hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500"
onClick={() => AddToGoogleCalendar(assignment.id)}
>
Добави в календар
</button>
<button
className="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
onClick={() => searchReplacement(assignment.id)}
>
Търси заместник
</button>
</dd>
</div>
</dl>
</div>
</div>
))}
</div>
</div>
</ProtectedRoute>
</Layout>
);
}
//get future assignmenrs for the current user (session.user.id)
//get future assignments for the current user (session.user.id)
export const getServerSideProps = async (context) => {
const session = await getSession(context);
@ -72,6 +108,7 @@ export const getServerSideProps = async (context) => {
if (assignment.shift && assignment.shift.startTime) {
return {
...assignment,
dateStr: assignment.shift.startTime.toLocaleDateString("bg-BG", { day: "numeric", month: "long" }),
shift: {
...assignment.shift,
startTime: assignment.shift.startTime.toISOString(),
@ -82,26 +119,10 @@ export const getServerSideProps = async (context) => {
return assignment;
});
const singleKey = "all";
const assignmentsStructure = {
assignments: {
items: {
[singleKey]: [],
},
keys: [singleKey],
months: {
[singleKey]: "Всички смени",
},
},
selectedtab: singleKey,
};
transformedAssignments.forEach(assignment => {
assignmentsStructure.assignments.items[singleKey].push(assignment);
});
return {
props: assignmentsStructure
props: { assignments: transformedAssignments }
}
}

View File

@ -0,0 +1,18 @@
-- AlterTable
ALTER TABLE `Availability` ADD COLUMN `dateOfEntry` DATETIME(3) NULL;
-- CreateTable
CREATE TABLE `Message` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`publisherId` VARCHAR(191) NOT NULL,
`date` DATETIME(3) NOT NULL,
`content` VARCHAR(191) NOT NULL,
`isRead` BOOLEAN NOT NULL DEFAULT false,
`isPublic` BOOLEAN NOT NULL DEFAULT false,
`type` ENUM('Email', 'SMS', 'Push', 'InApp') NOT NULL DEFAULT 'Email',
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- AddForeignKey
ALTER TABLE `Message` ADD CONSTRAINT `Message_publisherId_fkey` FOREIGN KEY (`publisherId`) REFERENCES `Publisher`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@ -133,7 +133,7 @@ model Availability {
repeatWeekly Boolean? // New field to indicate weekly repetition // until now dayofweek was used for repetition when dayOfMonth is null
repeatFrequency Int? // New field to indicate repetition frequency
endDate DateTime? // New field for the end date of repetition
//dateOfEntry DateTime? //NEW v1.0.1 trade storage for intuintivity
dateOfEntry DateTime? //NEW v1.0.1 trade storage for intuintivity
}
model CartEvent {