diff --git a/.gitignore b/.gitignore index f55a550..4339447 100644 --- a/.gitignore +++ b/.gitignore @@ -35,7 +35,5 @@ content/output/* public/content/output/* public/content/output/shifts 2024.1.json !public/content/uploads/* -shift_generate_log_*.txt -.aider.input.history -.aider.chat.history.md -.aider.tags.cache.v3/* +.aider* +/shift_generate_log_*.txt diff --git a/_deploy/entrypoint.sh b/_deploy/entrypoint.sh index 963c99f..81d1d76 100644 --- a/_deploy/entrypoint.sh +++ b/_deploy/entrypoint.sh @@ -39,6 +39,8 @@ if [ "$UPDATE_CODE_FROM_GIT" = "true" ]; then rsync -av --itemize-changes \ --exclude='package.json' \ --exclude='package-lock.json' \ + --exclude='/public/content/permits' \ + --exclude='/public/content/uploads' \ /tmp/clone/ /app/ >> /app/logs/deploy.txt 2>&1 # Check rsync exit status diff --git a/_doc/notes.mb b/_doc/notes.mb index 1236258..e6ed6a4 100644 --- a/_doc/notes.mb +++ b/_doc/notes.mb @@ -118,6 +118,11 @@ next start export OPENAI_API_KEY=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 # personal export OPENAI_API_KEY=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 # dev-bro + aider --openai-api-key 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 --no-auto-commits -- + + ## build - prod +npx run build +npm run prod # ----------------------------------------------update PRISMA schema/sync database ----------------------------------------------- # # prisma migrate dev --create-only NODE_ENV=production npx prisma migrate deploy diff --git a/components/calendar/avcalendar.tsx b/components/calendar/avcalendar.tsx index f83f238..e5e5ebc 100644 --- a/components/calendar/avcalendar.tsx +++ b/components/calendar/avcalendar.tsx @@ -51,10 +51,15 @@ const messages = { const AvCalendar = ({ publisherId, events, selectedDate, cartEvents, lastPublishedDate }) => { const [editLockedBefore, setEditLockedBefore] = useState(new Date(lastPublishedDate)); const [isAdmin, setIsAdmin] = useState(false); + // const [isPowerUser, setIsPowerUser] = useState(false); + // const [currentUserId, setCurrentUserId] = useState(null); useEffect(() => { (async () => { try { setIsAdmin(await ProtectedRoute.IsInRole(UserRole.ADMIN)); + // setIsPowerUser(await ProtectedRoute.IsInRole(UserRole.POWERUSER)); + // // Assuming you have a way to get the current user's ID + // setCurrentUserId(await ProtectedRoute.GetCurrentUserId()); } catch (error) { console.error("Failed to check admin role:", error); } @@ -256,7 +261,9 @@ const AvCalendar = ({ publisherId, events, selectedDate, cartEvents, lastPublish const enddate = common.setTimezone(end); if (!start || !end) return; - //readonly for past dates (ToDo: if not admin) + //readonly for past dates (ToDo: if not admin or current user) + //const isCurrentUser = selectedEvents.some(event => event.userId === currentUserId); + if (!isAdmin) { if (startdate < new Date() || end < new Date() || startdate > end) return; //or if schedule is published (lastPublishedDate) diff --git a/components/protectedRoute.tsx b/components/protectedRoute.tsx index 102e2a1..d77d107 100644 --- a/components/protectedRoute.tsx +++ b/components/protectedRoute.tsx @@ -85,5 +85,10 @@ export async function serverSideAuth({ req, allowedRoles }) { // Static method to check if the user has a specific role ProtectedRoute.IsInRole = async (roleName) => { const session = await getSession(); - return session && session.user && session.user.role === roleName; -}; \ No newline at end of file + return (session && session.user && session.user.role === roleName) || false; +}; + +ProtectedRoute.GetCurrentUserId = async () => { + const session = await getSession(); + return session && session.user && session.user.id; +} \ No newline at end of file diff --git a/components/publisher/PublisherCard.js b/components/publisher/PublisherCard.js index 1b01dd5..0f8c156 100644 --- a/components/publisher/PublisherCard.js +++ b/components/publisher/PublisherCard.js @@ -1,5 +1,5 @@ import Link from "next/link"; -import { Publisher } from "@prisma/client" +import { Publisher, UserRole } from "@prisma/client" // import {IsDateXMonthsAgo} from "../../helpers/const" import { useEffect, useState } from 'react' import toast from "react-hot-toast"; @@ -97,26 +97,27 @@ export default function PublisherCard({ publisher }) {
За да качите файл кликнете на бутона по-долу и изберете файл от вашия компютър.
diff --git a/public/content/permits/9- Разрешително за Септември 24г..pdf b/public/content/permits/9- Разрешително за Септември 24г..pdf new file mode 100644 index 0000000..bdfcfa9 Binary files /dev/null and b/public/content/permits/9- Разрешително за Септември 24г..pdf differ diff --git a/src/helpers/calendar.js b/src/helpers/calendar.js index 4d4541a..b990f99 100644 --- a/src/helpers/calendar.js +++ b/src/helpers/calendar.js @@ -17,7 +17,7 @@ const CREDENTIALS_PATH = path.join( ); //generates iCalendar file for a single shift -GenerateICS = function (shifts) { +const GenerateICS = function (shifts) { // https://stackoverflow.com/questions/3665115/create-a-file-in-memory-for-user-to-download-not-through-server var content = "BEGIN:VCALENDAR\n"; @@ -174,76 +174,76 @@ GenerateICS = function (shifts) { // const TOKEN_PATH = path.join(process.cwd(), 'content/token.json'); // const CREDENTIALS_PATH = path.join(process.cwd(), 'content/client_secret_926212607479-d3m8hm8f8esp3rf1639prskn445sa01v.apps.googleusercontent.com.json'); -createEvent = async function createEvent(id) { - // var eventTest2 = { - // 'summary': 'Google I/O 2015', - // 'location': '800 Howard St., San Francisco, CA 94103', - // 'description': 'A chance to hear more about Google\'s developer products.', - // 'start': { - // 'dateTime': '2015-05-28T09:00:00-07:00', - // 'timeZone': 'America/Los_Angeles', - // }, - // 'end': { - // 'dateTime': '2015-05-28T17:00:00-07:00', - // 'timeZone': 'America/Los_Angeles', - // }, - // 'recurrence': [ - // 'RRULE:FREQ=DAILY;COUNT=2' - // ], - // 'attendees': [ - // { 'email': '' }, +// const createEvent = async function createEvent(id) { +// // var eventTest2 = { +// // 'summary': 'Google I/O 2015', +// // 'location': '800 Howard St., San Francisco, CA 94103', +// // 'description': 'A chance to hear more about Google\'s developer products.', +// // 'start': { +// // 'dateTime': '2015-05-28T09:00:00-07:00', +// // 'timeZone': 'America/Los_Angeles', +// // }, +// // 'end': { +// // 'dateTime': '2015-05-28T17:00:00-07:00', +// // 'timeZone': 'America/Los_Angeles', +// // }, +// // 'recurrence': [ +// // 'RRULE:FREQ=DAILY;COUNT=2' +// // ], +// // 'attendees': [ +// // { 'email': '' }, - // ], - // 'reminders': { - // 'useDefault': false, - // 'overrides': [ - // { 'method': 'email', 'minutes': 24 * 60 }, - // { 'method': 'popup', 'minutes': 10 }, - // ], - // }, - // }; - // var errors; - // var auth = await exports.authorize().then((auth) => { +// // ], +// // 'reminders': { +// // 'useDefault': false, +// // 'overrides': [ +// // { 'method': 'email', 'minutes': 24 * 60 }, +// // { 'method': 'popup', 'minutes': 10 }, +// // ], +// // }, +// // }; +// // var errors; +// // var auth = await exports.authorize().then((auth) => { - // const calendar = google.calendar({ version: 'v3', auth }); - // const res = calendar.events.insert({ - // calendarId: 'primary', - // resource: eventTest, +// // const calendar = google.calendar({ version: 'v3', auth }); +// // const res = calendar.events.insert({ +// // calendarId: 'primary', +// // resource: eventTest, - // }, (err, event) => { - // if (err) { - // console.log(`There was an error creating the event: ${err}`); - // return; - // } - // console.log(`Event created: ${event.data.htmlLink}`); - // }); - // }).catch(console.error).then((err) => { - // errors = err; - // }); - // return errors; - // } +// // }, (err, event) => { +// // if (err) { +// // console.log(`There was an error creating the event: ${err}`); +// // return; +// // } +// // console.log(`Event created: ${event.data.htmlLink}`); +// // }); +// // }).catch(console.error).then((err) => { +// // errors = err; +// // }); +// // return errors; +// // } - // authorizeNew = async function authorizeNew() { - // let client = await loadSavedCredentialsIfExist(); - // if (client) { - // return client; - // } - // // Set up the Google Calendar API client - // const calendar = google.calendar({ version: 'v3', auth }); +// // authorizeNew = async function authorizeNew() { +// // let client = await loadSavedCredentialsIfExist(); +// // if (client) { +// // return client; +// // } +// // // Set up the Google Calendar API client +// // const calendar = google.calendar({ version: 'v3', auth }); - // // Load the client secrets from a JSON file +// // // Load the client secrets from a JSON file - fs.readFile("./path/to/client_secret.json", (err, content) => { - if (err) return console.error("Error loading client secret file:", err); +// fs.readFile("./path/to/client_secret.json", (err, content) => { +// if (err) return console.error("Error loading client secret file:", err); - // Authorize a client with the loaded credentials - authorizeOA(JSON.parse(content), calendar.calendarList.list); - }); - if (client.credentials) { - await saveCredentials(client); - } - return client; -}; +// // Authorize a client with the loaded credentials +// authorizeOA(JSON.parse(content), calendar.calendarList.list); +// }); +// if (client.credentials) { +// await saveCredentials(client); +// } +// return client; +// }; // var googletoken = axiosInstance.get("/content/google_token.json"); // console.log("googletoken: " + googletoken); @@ -372,7 +372,7 @@ async function importModules() { }; } -createEvent = async (event) => { +const createEvent = async (event) => { const { open, getPort } = await importModules(); @@ -474,7 +474,7 @@ createEvent = async (event) => { } }; -SaveEventsInGoogleCalendar = async function SaveEventsInGoogleCalendar(events) { +const SaveEventsInGoogleCalendar = async function SaveEventsInGoogleCalendar(events) { // Load client secrets from a local file. try { const content = await fs.readFile(CREDENTIALS_PATH); diff --git a/src/helpers/email.js b/src/helpers/email.js index 1ae49ce..47afdad 100644 --- a/src/helpers/email.js +++ b/src/helpers/email.js @@ -5,7 +5,7 @@ const path = require('path'); const { MailtrapClient } = require("mailtrap"); const nodemailer = require("nodemailer"); const CON = require("./const"); -const CAL = require("./calendar"); +const { GenerateICS } = require("./calendar"); const common = require("./common"); const Handlebars = require('handlebars');