diff --git a/components/publisher/PublisherForm.js b/components/publisher/PublisherForm.js
index e851008..1e39d46 100644
--- a/components/publisher/PublisherForm.js
+++ b/components/publisher/PublisherForm.js
@@ -19,34 +19,6 @@ import { useSession } from "next-auth/react"
// import { Tabs, List } from 'tw-elements'
-// model Publisher {
-// id String @id @default(cuid())
-// firstName String
-// lastName String
-// email String @unique
-// phone String?
-// isActive Boolean @default(true)
-// isImported Boolean @default(false)
-// age Int?
-// availabilities Availability[]
-// assignments Assignment[]
-
-// emailVerified DateTime?
-// accounts Account[]
-// sessions Session[]
-// role UserRole @default(USER)
-// desiredShiftsPerMonth Int @default(4)
-// isMale Boolean @default(true)
-// isNameForeign Boolean @default(false)
-
-// familyHeadId String? // Optional familyHeadId for each family member
-// familyHead Publisher? @relation("FamilyMember", fields: [familyHeadId], references: [id])
-// familyMembers Publisher[] @relation("FamilyMember")
-// type PublisherType @default(Publisher)
-// Town String?
-// Comments String?
-// }
-
Array.prototype.groupBy = function (prop) {
return this.reduce(function (groups, item) {
const val = item[prop]
@@ -59,9 +31,11 @@ Array.prototype.groupBy = function (prop) {
export default function PublisherForm({ item, me }) {
const router = useRouter();
const { data: session } = useSession()
+ const [congregations, setCongregations] = useState([]);
const urls = {
apiUrl: "/api/data/publishers/",
+ congregationsUrl: "/api/data/congregations",
indexUrl: session?.user?.role == UserRole.ADMIN ? "/cart/publishers" : "/dash"
}
console.log("urls.indexUrl: " + urls.indexUrl);
@@ -72,6 +46,9 @@ export default function PublisherForm({ item, me }) {
const h = (await import("../../src/helpers/const.js")).default;
//console.log("fetchModules: " + JSON.stringify(h));
setHelper(h);
+
+ const response = await axiosInstance.get(urls.congregationsUrl);
+ setCongregations(response.data);
}
useEffect(() => {
fetchModules();
@@ -113,15 +90,17 @@ export default function PublisherForm({ item, me }) {
publisher.availabilities = undefined;
publisher.assignments = undefined;
- let { familyHeadId, userId, ...rest } = publisher;
+ let { familyHeadId, userId, congregationId, ...rest } = publisher;
// Set the familyHead relation based on the selected head
const familyHeadRelation = familyHeadId ? { connect: { id: familyHeadId } } : { disconnect: true };
const userRel = userId ? { connect: { id: userId } } : { disconnect: true };
+ const congregationRel = congregationId ? { connect: { id: parseInt(congregationId) } } : { disconnect: true };
// Return the new state without familyHeadId and with the correct familyHead relation
rest = {
...rest,
familyHead: familyHeadRelation,
- user: userRel
+ user: userRel,
+ congregation: congregationRel
};
try {
@@ -246,6 +225,19 @@ export default function PublisherForm({ item, me }) {
+
+
+
+
+
+
{/* notifications */}
diff --git a/pages/api/auth/[...nextauth].ts b/pages/api/auth/[...nextauth].ts
index 8cb4f4d..098b95b 100644
--- a/pages/api/auth/[...nextauth].ts
+++ b/pages/api/auth/[...nextauth].ts
@@ -56,11 +56,11 @@ export const authOptions: NextAuthOptions = {
keyId: process.env.APPLE_KEY_ID,
}
}),
- // AzureADProvider({
- // clientId: process.env.AZURE_AD_CLIENT_ID,
- // clientSecret: process.env.AZURE_AD_CLIENT_SECRET,
- // tenantId: process.env.AZURE_AD_TENANT_ID,
- // }),
+ AzureADProvider({
+ clientId: process.env.AZURE_AD_CLIENT_ID,
+ clientSecret: process.env.AZURE_AD_CLIENT_SECRET,
+ tenantId: process.env.AZURE_AD_TENANT_ID,
+ }),
CredentialsProvider({
id: 'credentials',
// The name to display on the sign in form (e.g. 'Sign in with...')
diff --git a/pages/auth/signin.tsx b/pages/auth/signin.tsx
index 9904a52..ceccfdd 100644
--- a/pages/auth/signin.tsx
+++ b/pages/auth/signin.tsx
@@ -74,6 +74,13 @@ export default function SignIn({ csrfToken }) {
src="https://authjs.dev/img/providers/apple.svg" className="mr-2" />
Влез чрез Apple
*/}
+ {/* microsoft */}
+ {/*
*/}
diff --git a/pages/cart/locations/index.tsx b/pages/cart/locations/index.tsx
index 716993a..e6b5b44 100644
--- a/pages/cart/locations/index.tsx
+++ b/pages/cart/locations/index.tsx
@@ -4,6 +4,7 @@ import Layout from "../../../components/layout";
import LocationCard from "../../../components/location/LocationCard";
import axiosServer from '../../../src/axiosServer';
import ProtectedRoute from '../../../components/protectedRoute';
+import CongregationCRUD from "../publishers/congregationCRUD";
interface IProps {
item: Location;
}
@@ -32,6 +33,7 @@ function LocationsPage({ items = [] }: IProps) {
+
);
}
diff --git a/pages/cart/publishers/congregationCRUD.tsx b/pages/cart/publishers/congregationCRUD.tsx
new file mode 100644
index 0000000..95d0e43
--- /dev/null
+++ b/pages/cart/publishers/congregationCRUD.tsx
@@ -0,0 +1,103 @@
+// a simple CRUD componenet for congregations for admins
+
+import { useEffect, useState } from 'react';
+import axiosInstance from '../../../src/axiosSecure';
+import toast from 'react-hot-toast';
+import Layout from '../../../components/layout';
+import ProtectedRoute from '../../../components/protectedRoute';
+import { UserRole } from '@prisma/client';
+import { useRouter } from 'next/router';
+
+export default function CongregationCRUD() {
+ const [congregations, setCongregations] = useState([]);
+ const [newCongregation, setNewCongregation] = useState('');
+ const router = useRouter();
+
+ const fetchCongregations = async () => {
+ try {
+ const { data: congregationsData } = await axiosInstance.get(`/api/data/congregations`);
+ setCongregations(congregationsData);
+ } catch (error) {
+ console.error(error);
+ }
+ };
+
+ const addCongregation = async () => {
+ try {
+ await axiosInstance.post(`/api/data/congregations`, { name: newCongregation, address: "" });
+ toast.success('Успешно добавен сбор');
+ setNewCongregation('');
+ fetchCongregations();
+ } catch (error) {
+ console.error(error);
+ }
+ };
+
+ const deleteCongregation = async (id) => {
+ try {
+ await axiosInstance.delete(`/api/data/congregations/${id}`);
+ toast.success('Успешно изтрит сбор');
+ fetchCongregations();
+ } catch (error) {
+ console.error(error);
+ }
+ };
+ useEffect(() => {
+ fetchCongregations();
+ }, []);
+
+ return (
+
+
+
+
Сборове
+
+ setNewCongregation(e.target.value)}
+ placeholder="Име на сбор"
+ className="px-4 py-2 rounded-md border border-gray-300"
+ />
+
+
+
+
+
+ Име |
+ Действия |
+
+
+
+ {congregations.map((congregation) => (
+
+ {congregation.name} |
+
+ {/* */}
+
+ |
+
+ ))}
+
+
+
+
+
+ );
+}
+
diff --git a/prisma/migrations/20240510131656_publisher_congregation/migration.sql b/prisma/migrations/20240510131656_publisher_congregation/migration.sql
new file mode 100644
index 0000000..133bedf
--- /dev/null
+++ b/prisma/migrations/20240510131656_publisher_congregation/migration.sql
@@ -0,0 +1,33 @@
+-- AlterTable
+ALTER TABLE `Assignment`
+ADD COLUMN `originalPublisherId` VARCHAR(191) NULL;
+
+-- AlterTable
+ALTER TABLE `Message` ADD COLUMN `publicUntil` DATETIME(3) NULL;
+
+-- AlterTable
+ALTER TABLE `Publisher`
+ADD COLUMN `congregationId` INTEGER NULL,
+ADD COLUMN `locale` VARCHAR(191) NULL DEFAULT 'bg';
+
+-- AlterTable
+ALTER TABLE `Report` ADD COLUMN `comments` VARCHAR(191) NULL;
+
+-- CreateTable
+CREATE TABLE `Congregation` (
+ `id` INTEGER NOT NULL AUTO_INCREMENT,
+ `name` VARCHAR(191) NOT NULL,
+ `address` VARCHAR(191) NOT NULL,
+ `isActive` BOOLEAN NOT NULL DEFAULT true,
+
+
+ PRIMARY KEY (`id`)
+) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
+
+-- AddForeignKey
+ALTER TABLE `Publisher`
+ADD CONSTRAINT `Publisher_congregationId_fkey` FOREIGN KEY (`congregationId`) REFERENCES `Congregation` (`id`) ON DELETE SET NULL ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE `Assignment`
+ADD CONSTRAINT `Assignment_originalPublisherId_fkey` FOREIGN KEY (`originalPublisherId`) REFERENCES `Publisher` (`id`) ON DELETE SET NULL ON UPDATE CASCADE;
\ No newline at end of file
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index 391079f..8341d0d 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -124,6 +124,18 @@ model Publisher {
EventLog EventLog[]
lastLogin DateTime?
pushSubscription Json?
+ originalAssignments Assignment[] @relation("OriginalPublisher")
+ congregation Congregation? @relation(fields: [congregationId], references: [id])
+ congregationId Int?
+ locale String? @default("bg")
+}
+
+model Congregation {
+ id Int @id @default(autoincrement())
+ name String
+ address String
+ isActive Boolean @default(true)
+ publishers Publisher[]
}
model Availability {
@@ -181,23 +193,25 @@ model Shift {
//date DateTime
reportId Int? @unique
Report Report? @relation(fields: [reportId], references: [id])
- isPublished Boolean @default(false) //NEW v1.0.1
+ isPublished Boolean @default(false)
EventLog EventLog[]
@@map("Shift")
}
model Assignment {
- id Int @id @default(autoincrement())
- shift Shift @relation(fields: [shiftId], references: [id], onDelete: Cascade)
- shiftId Int
- publisher Publisher @relation(fields: [publisherId], references: [id], onDelete: Cascade)
- publisherId String
- isBySystem Boolean @default(false) // if no availability for it, when importing previous schedules
- isConfirmed Boolean @default(false)
- isWithTransport Boolean @default(false)
- isMailSent Boolean @default(false)
- publicGuid String? @unique
+ id Int @id @default(autoincrement())
+ shift Shift @relation(fields: [shiftId], references: [id], onDelete: Cascade)
+ shiftId Int
+ publisher Publisher @relation(fields: [publisherId], references: [id], onDelete: Cascade)
+ publisherId String
+ isBySystem Boolean @default(false) // if no availability for it, when importing previous schedules
+ isConfirmed Boolean @default(false)
+ isWithTransport Boolean @default(false)
+ isMailSent Boolean @default(false)
+ publicGuid String? @unique
+ originalPublisherId String? // New field to store the original publisher id when the assignment is replaced
+ originalPublisher Publisher? @relation("OriginalPublisher", fields: [originalPublisherId], references: [id])
@@map("Assignment")
}
@@ -237,6 +251,7 @@ model Report {
experienceInfo String? @db.LongText
type ReportType @default(ServiceReport)
+ comments String?
@@map("Report")
}
@@ -258,6 +273,7 @@ model Message {
isRead Boolean @default(false)
isPublic Boolean @default(false)
type MessageType @default(Email)
+ publicUntil DateTime?
}
enum EventLogType {