Merge branch 'main' of https://git.d-popov.com/popov/mwhitnessing
This commit is contained in:
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@ -144,5 +144,8 @@
|
|||||||
"components/x-date-pickers/locales"
|
"components/x-date-pickers/locales"
|
||||||
],
|
],
|
||||||
"i18n-ally.keystyle": "nested",
|
"i18n-ally.keystyle": "nested",
|
||||||
"i18n-ally.sourceLanguage": "bg"
|
"i18n-ally.sourceLanguage": "bg",
|
||||||
|
"[shellscript]": {
|
||||||
|
"editor.defaultFormatter": "foxundermoon.shell-format"
|
||||||
|
}
|
||||||
}
|
}
|
@ -9,6 +9,7 @@ services:
|
|||||||
# - "3000:3000"
|
# - "3000:3000"
|
||||||
volumes:
|
volumes:
|
||||||
- /mnt/docker_volumes/pw/app/public/content/uploads/:/app/public/content/uploads
|
- /mnt/docker_volumes/pw/app/public/content/uploads/:/app/public/content/uploads
|
||||||
|
- /mnt/docker_volumes/pw/app/logs:/app/logs
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=production
|
- NODE_ENV=production
|
||||||
- TZ=Europe/Sofia
|
- TZ=Europe/Sofia
|
||||||
@ -19,7 +20,7 @@ services:
|
|||||||
- GIT_USERNAME=deploy
|
- GIT_USERNAME=deploy
|
||||||
- GIT_PASSWORD=L3Kr2R438u4F7
|
- GIT_PASSWORD=L3Kr2R438u4F7
|
||||||
- ADMIN_PASSWORD=changeme
|
- ADMIN_PASSWORD=changeme
|
||||||
command: sh -c " cd /app && npm install && npm run prod; tail -f /dev/null"
|
command: sh -c " cd /app && npm install && npx next build && npm run prod; tail -f /dev/null"
|
||||||
#command: sh -c " cd /app && tail -f /dev/null"
|
#command: sh -c " cd /app && tail -f /dev/null"
|
||||||
tty: true
|
tty: true
|
||||||
stdin_open: true
|
stdin_open: true
|
||||||
@ -56,15 +57,15 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- infrastructure_default
|
- infrastructure_default
|
||||||
command: |
|
command: |
|
||||||
apk update && \
|
"apk update && \
|
||||||
apk add --no-cache mariadb-client mariadb-connector-c && \
|
apk add --no-cache mariadb-client mariadb-connector-c && \
|
||||||
echo '0 2 * * * mysqldump -h $$MYSQL_HOST -P 3306 -u$$MYSQL_USER -p$$MYSQL_PASSWORD $$MYSQL_DATABASE > /backup/$$(date +\\%Y-\\%m-\\%d-\\%H\\%M\\%S)-$$MYSQL_DATABASE.sql' > /etc/crontabs/root && \
|
echo '0 2 * * * mysqldump -h $$MYSQL_HOST -P 3306 -u$$MYSQL_USER -p$$MYSQL_PASSWORD $$MYSQL_DATABASE > /backup/$$(date +\\%Y-\\%m-\\%d-\\%H\\%M\\%S)-$$MYSQL_DATABASE.sql' > /etc/crontabs/root && \
|
||||||
echo '0 7 * * * rclone sync /backup nextcloud:/mwitnessing' >> /etc/crontabs/root && \
|
crond -f -d 8"
|
||||||
crond -f -d 8
|
|
||||||
# wget -q https://github.com/prasmussen/gdrive/releases/download/2.1.0/gdrive-linux-x64 -O /usr/bin/gdrive && \
|
# wget -q https://github.com/prasmussen/gdrive/releases/download/2.1.0/gdrive-linux-x64 -O /usr/bin/gdrive && \
|
||||||
# chmod +x /usr/bin/gdrive && \
|
# chmod +x /usr/bin/gdrive && \
|
||||||
# gdrive about --service-account /root/.gdrive_service_account.json && \
|
# gdrive about --service-account /root/.gdrive_service_account.json && \
|
||||||
# echo '0 * * * * /usr/bin/mysqldump -h $$MYSQL_HOST -u$$MYSQL_USER -p$$MYSQL_PASSWORD $$MYSQL_DATABASE | gzip > /backup/$$(date +\\%Y-\\%m-\\%d-\\%H\\%M\\%S)-$$MYSQL_DATABASE.sql.gz && gdrive upload --parent $$GOOGLE_DRIVE_FOLDER_ID --service-account /root/.gdrive_service_account.json /backup/$$(date +\\%Y-\\%m-\\%d-\\%H\\%M\\%S)-$$MYSQL_DATABASE.sql.gz' > /etc/crontabs/root && crond -f -d 8"
|
# echo '0 * * * * /usr/bin/mysqldump -h $$MYSQL_HOST -u$$MYSQL_USER -p$$MYSQL_PASSWORD $$MYSQL_DATABASE | gzip > /backup/$$(date +\\%Y-\\%m-\\%d-\\%H\\%M\\%S)-$$MYSQL_DATABASE.sql.gz && gdrive upload --parent $$GOOGLE_DRIVE_FOLDER_ID --service-account /root/.gdrive_service_account.json /backup/$$(date +\\%Y-\\%m-\\%d-\\%H\\%M\\%S)-$$MYSQL_DATABASE.sql.gz' > /etc/crontabs/root && crond -f -d 8 \
|
||||||
|
# echo '0 7 * * * rclone sync /backup nextcloud:/mwitnessing --delete-excluded ' >> /etc/crontabs/root && \"
|
||||||
networks:
|
networks:
|
||||||
infrastructure_default:
|
infrastructure_default:
|
||||||
external: true
|
external: true
|
||||||
|
@ -3,18 +3,72 @@
|
|||||||
if [ "$UPDATE_CODE_FROM_GIT" = "true" ]; then
|
if [ "$UPDATE_CODE_FROM_GIT" = "true" ]; then
|
||||||
# Install necessary packages
|
# Install necessary packages
|
||||||
apk add git nano rsync
|
apk add git nano rsync
|
||||||
echo "Updating code from git.d-popov.com...(as '$GIT_USERNAME')"
|
echo "Updating code from git.d-popov.com...(as '$GIT_USERNAME')" > /app/logs/deploy.txt
|
||||||
|
|
||||||
# Create a temporary directory for the new clone
|
# Create a temporary directory for the new clone
|
||||||
rm -rf /tmp/clone
|
rm -rf /tmp/clone
|
||||||
mkdir /tmp/clone
|
mkdir /tmp/clone
|
||||||
|
mkdir -p /app/logs
|
||||||
|
|
||||||
|
# Clear previous log
|
||||||
|
echo "Starting sync process at $(date)" > /app/logs/deploy.txt
|
||||||
# Clone the repository
|
# Clone the repository
|
||||||
git clone -b ${GIT_BRANCH:-main} --depth 1 https://$GIT_USERNAME:${GIT_PASSWORD//@/%40}@git.d-popov.com/popov/mwitnessing.git /tmp/clone || exit 1
|
echo "\r\n\r\n Cloning repository..." | tee -a logs/deploy.txt
|
||||||
|
git clone -b ${GIT_BRANCH:main} --depth 1 https://$GIT_USERNAME:${GIT_PASSWORD//@/%40}@git.d-popov.com/popov/mwitnessing.git /tmp/clone || exit 1
|
||||||
|
|
||||||
# Synchronize all files except package.json and package-lock.json to /app
|
# Synchronize all files except package.json, package-lock.json, and the contents of /public/content
|
||||||
rsync -av --delete --exclude 'package.json' --exclude 'package-lock.json' /tmp/clone/ /app/ || echo "Rsync failed: Issue synchronizing files"
|
# rsync -av --filter='P /public/content/' --exclude 'package.json' --exclude 'package-lock.json' /tmp/clone/ /app/ || echo "Rsync failed: Issue synchronizing files"
|
||||||
|
echo "\r\n\r\n Synchronizing files..."
|
||||||
|
rsync -av /tmp/clone/_deploy/entrypoint.sh /app/entrypoint.sh || echo "Rsync failed: Issue copying entrypoint.sh"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# rsync -av --update --exclude '/public/content' --exclude 'package.json' --exclude 'package-lock.json' /tmp/clone/ /app/ || echo "Rsync failed: Issue synchronizing files" | tee -a /app/logs/deploy.txt
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################################
|
||||||
|
if [ -d "/app/public/content/permits" ]; then
|
||||||
|
mv /app/public/content/permits /tmp/content/permits
|
||||||
|
echo "Permits folder backed up successfully." | tee -a /app/logs/deploy.txt
|
||||||
|
else
|
||||||
|
echo "Permits folder not found, skipping backup." | tee -a /app/logs/deploy.txt
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run rsync with verbose output and itemize-changes
|
||||||
|
echo "Running rsync..." | tee -a /app/logs/deploy.txt
|
||||||
|
rsync -av --itemize-changes \
|
||||||
|
--exclude='package.json' \
|
||||||
|
--exclude='package-lock.json' \
|
||||||
|
/tmp/clone/ /app/ >> /app/logs/deploy.txt 2>&1
|
||||||
|
|
||||||
|
# Check rsync exit status
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Rsync failed: Issue synchronizing files" | tee -a /app/logs/deploy.txt
|
||||||
|
cat /app/logs/deploy.txt # Display the log contents
|
||||||
|
else
|
||||||
|
echo "Rsync completed successfully" | tee -a /app/logs/deploy.txt
|
||||||
|
echo "Last few lines of rsync log:" | tee -a /app/logs/deploy.txt
|
||||||
|
tail -n 20 /app/logs/deploy.txt # Display the last 20 lines of the log
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Restore permits folder
|
||||||
|
echo "Restoring permits folder..." | tee -a /app/logs/deploy.txt
|
||||||
|
if [ -d "/tmp/content/permits" ]; then
|
||||||
|
# Ensure the destination directory exists
|
||||||
|
mkdir -p /app/public/content
|
||||||
|
mv /tmp/content/permits /app/public/content/permits
|
||||||
|
echo "Permits folder restored successfully." | tee -a /app/logs/deploy.txt
|
||||||
|
else
|
||||||
|
echo "No permits folder to restore." | tee -a /app/logs/deploy.txt
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check contents after restoration
|
||||||
|
echo "Contents of /app/public/content after restoration:" >> /app/logs/deploy.txt
|
||||||
|
ls -la /app/public/content >> /app/logs/deploy.txt 2>&1
|
||||||
|
########################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
echo "\r\n\r\n Checking for changes in package files..."
|
||||||
# Determine if package.json or package-lock.json has changed
|
# Determine if package.json or package-lock.json has changed
|
||||||
PACKAGE_CHANGE=0
|
PACKAGE_CHANGE=0
|
||||||
if ! cmp -s /tmp/clone/package.json /app/package.json || ! cmp -s /tmp/clone/package-lock.json /app/package-lock.json; then
|
if ! cmp -s /tmp/clone/package.json /app/package.json || ! cmp -s /tmp/clone/package-lock.json /app/package-lock.json; then
|
||||||
@ -37,7 +91,7 @@ if [ "$UPDATE_CODE_FROM_GIT" = "true" ]; then
|
|||||||
npx next build
|
npx next build
|
||||||
|
|
||||||
# Clean up
|
# Clean up
|
||||||
rm -rf /tmp/clone
|
# rm -rf /tmp/clone
|
||||||
echo "Update process completed."
|
echo "Update process completed."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
43
_deploy/entrypoint.staging.sh
Normal file
43
_deploy/entrypoint.staging.sh
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
# Check if the environment variable to update code from git is set to true
|
||||||
|
if [ "$UPDATE_CODE_FROM_GIT" = "true" ]; then
|
||||||
|
# Install necessary packages
|
||||||
|
apk add git nano rsync
|
||||||
|
echo "Updating code from git.d-popov.com...(as '$GIT_USERNAME')"
|
||||||
|
|
||||||
|
# Remove the previous clone directory to ensure a fresh start
|
||||||
|
rm -rf /tmp/clone
|
||||||
|
mkdir /tmp/clone
|
||||||
|
|
||||||
|
# Clone the specific branch of the new repository
|
||||||
|
git clone -b ${GIT_BRANCH:-main} --depth 1 https://$GIT_USERNAME:${GIT_PASSWORD//@/%40}@git.d-popov.com/popov/mwitnessing.git /tmp/clone || exit 1
|
||||||
|
# Fetch the latest commit ID and message from the cloned repository
|
||||||
|
GIT_COMMIT_ID=$(git -C /tmp/clone rev-parse HEAD)
|
||||||
|
LAST_COMMIT_MESSAGE=$(git -C /tmp/clone log -1 --pretty=%B)
|
||||||
|
echo "Current Git Commit: $LAST_COMMIT_MESSAGE: $GIT_COMMIT_ID"
|
||||||
|
export GIT_COMMIT_ID
|
||||||
|
|
||||||
|
# Use rsync to synchronize the files to /app, including deletion of files not in the source
|
||||||
|
rsync -av --delete --exclude '/public/content' /tmp/clone/ /app/ || echo "Rsync failed: Issue synchronizing files"
|
||||||
|
# Copy .env files
|
||||||
|
rsync -av /tmp/clone/.env* /app/ || echo "Rsync failed: Issue copying .env files"
|
||||||
|
# Copy the entrypoint.sh if exists in the new structure
|
||||||
|
[ -f /tmp/clone/entrypoint.sh ] && rsync -av /tmp/clone/entrypoint.sh /app/entrypoint.sh || echo "Rsync failed: Issue copying entrypoint.sh"
|
||||||
|
chmod +x /app/entrypoint.sh
|
||||||
|
|
||||||
|
# Clean up the temporary clone directory
|
||||||
|
rm -rf /tmp/clone
|
||||||
|
|
||||||
|
cd /app
|
||||||
|
echo "Installing packages in /app"
|
||||||
|
npm install --no-audit --no-fund --no-optional --omit=optional
|
||||||
|
yes | npx prisma generate
|
||||||
|
# Uncomment the next line if database migrations are necessary
|
||||||
|
# npx prisma migrate deploy
|
||||||
|
echo "Done cloning. Current Git Commit ID: $GIT_COMMIT_ID"
|
||||||
|
# Uncomment the following lines for production deployment
|
||||||
|
# npx next build
|
||||||
|
# npx next start
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Running the main process"
|
||||||
|
exec "$@"
|
19
_deploy/new-lite/Dockerfile
Normal file
19
_deploy/new-lite/Dockerfile
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
FROM node:current-alpine
|
||||||
|
|
||||||
|
# Install git and curl
|
||||||
|
RUN apk add --no-cache git curl
|
||||||
|
|
||||||
|
# Set environment variables for repo and branch
|
||||||
|
# These will be overridden by docker-compose.yml
|
||||||
|
ENV REPO=""
|
||||||
|
ENV BRANCH=""
|
||||||
|
|
||||||
|
# Create a directory for the app
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Download the entrypoint script
|
||||||
|
CMD git clone --depth 1 --branch $BRANCH $REPO /tmp/repo && \
|
||||||
|
cp /tmp/repo/_deploy/entrypoint.sh /app/entrypoint.sh && \
|
||||||
|
chmod +x /app/entrypoint.sh && \
|
||||||
|
rm -rf /tmp/repo && \
|
||||||
|
/app/entrypoint.sh
|
10
_doc/ToDo.md
10
_doc/ToDo.md
@ -262,4 +262,12 @@ in schedule admin - if a publisher is always pair & family is not in the shift -
|
|||||||
[] allow blocking of inputs (different from publishing) TODO: fix to keep previous occurances when repeating evert week
|
[] allow blocking of inputs (different from publishing) TODO: fix to keep previous occurances when repeating evert week
|
||||||
[] user - add createdAt field
|
[] user - add createdAt field
|
||||||
|
|
||||||
[] FIX insecure logins
|
[x] FIX insecure logins
|
||||||
|
|
||||||
|
[] nove push to form, - reorganize pWAManager to have session, role, subscriptions, etc...
|
||||||
|
[] add shift name in calendar/ show in schedule if no assignments.
|
||||||
|
[] show unpublished schedule if admin
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,8 +25,8 @@ apt install nodejs -y
|
|||||||
|
|
||||||
##### ----------------- compose/deploy ----------------- ###
|
##### ----------------- compose/deploy ----------------- ###
|
||||||
# install docker if inside docker (vscode-server)# apt-get update && apt-get install -y docker.io
|
# install docker if inside docker (vscode-server)# apt-get update && apt-get install -y docker.io
|
||||||
# .10 > /mnt/apps/DEV/SSS/next-cart-app/next-cart-app/
|
# !!! .10 > /mnt/apps/DEV/SSS/next-cart-app/next-cart-app/
|
||||||
#.11 > cd /mnt/storage/DEV/workspace/repos/git.d-popov.com/next-cart-app/next-cart-app
|
# !!! .11 > cd /mnt/storage/DEV/workspace/repos/git.d-popov.com/next-cart-app/next-cart-app
|
||||||
|
|
||||||
# using dockerfile and image:
|
# using dockerfile and image:
|
||||||
docker build -t jwpw:latest -f _deploy/prod.Dockerfile .
|
docker build -t jwpw:latest -f _deploy/prod.Dockerfile .
|
||||||
@ -46,9 +46,9 @@ docker push docker.d-popov.com/jwpw:test
|
|||||||
--LATEST/
|
--LATEST/
|
||||||
cd /mnt/storage/DEV/workspace/repos/git.d-popov.com/mwhitnessing
|
cd /mnt/storage/DEV/workspace/repos/git.d-popov.com/mwhitnessing
|
||||||
docker build -t docker.d-popov.com/jwpw:latest -f _deploy/prod.Dockerfile .
|
docker build -t docker.d-popov.com/jwpw:latest -f _deploy/prod.Dockerfile .
|
||||||
docker tag docker.d-popov.com/jwpw:latest docker.d-popov.com/jwpw:0.9.95
|
docker tag docker.d-popov.com/jwpw:latest docker.d-popov.com/jwpw:1.3.5
|
||||||
docker push docker.d-popov.com/jwpw:latest
|
docker push docker.d-popov.com/jwpw:latest
|
||||||
docker push docker.d-popov.com/jwpw:0.9.95
|
docker push docker.d-popov.com/jwpw:1.3.5
|
||||||
|
|
||||||
#---
|
#---
|
||||||
|
|
||||||
@ -221,7 +221,8 @@ curl https://gist.githubusercontent.com/balazsorban44/09613175e7b37ec03f676dcefb
|
|||||||
################### sync folders
|
################### sync folders
|
||||||
# nc: WebDAV
|
# nc: WebDAV
|
||||||
apk add rclone
|
apk add rclone
|
||||||
rclone config
|
rclone config
|
||||||
|
/52 https://cloud.d-popov.com sync syncsyncsyncsyncsyncsyncsync
|
||||||
rclone sync /path/to/local/folder yourRemoteName:target-folder
|
rclone sync /path/to/local/folder yourRemoteName:target-folder
|
||||||
# nc
|
# nc
|
||||||
sudo add-apt-repository ppa:nextcloud-devs/client
|
sudo add-apt-repository ppa:nextcloud-devs/client
|
||||||
@ -236,9 +237,11 @@ rclone config
|
|||||||
rclone lsd nextcloud: # {nc=remotename}
|
rclone lsd nextcloud: # {nc=remotename}
|
||||||
rclone sync /path/to/local/folder gdrive:target-folder
|
rclone sync /path/to/local/folder gdrive:target-folder
|
||||||
rclone sync /backup nextcloud:/mwitnessing [--dry-run] [--progress]
|
rclone sync /backup nextcloud:/mwitnessing [--dry-run] [--progress]
|
||||||
rclone sync /backup nextcloud:/mwitnessing --dry-run --progress
|
# pw-mariadb_backup-1
|
||||||
|
rclone sync /backup nextcloud:/mwitnessing --dry-run --progress --delete-excluded
|
||||||
|
rclone sync /mnt/docker_volumes/pw/data/backup nc:/mwitnessing --dry-run --progress
|
||||||
crontab -e
|
crontab -e
|
||||||
0 7 * * * rclone sync /backup nextcloud:/mwitnessing
|
0 7 * * * rclone sync /backup nextcloud:/mwitnessing --delete-excluded
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ class ErrorBoundary extends React.Component {
|
|||||||
render() {
|
render() {
|
||||||
if (this.state.hasError) {
|
if (this.state.hasError) {
|
||||||
// Render any custom fallback UI
|
// Render any custom fallback UI
|
||||||
return <h1>Нещо се обърка при изтриването. Моля, опитай отново и се свържете с нас ако проблема продължи. </h1>;
|
return <h1>Нещо се обърка. Моля, опитай отново и се свържете с нас ако проблема продължи. </h1>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.props.children;
|
return this.props.children;
|
||||||
|
@ -6,7 +6,7 @@ import e from 'express';
|
|||||||
import ProtectedRoute from './protectedRoute';
|
import ProtectedRoute from './protectedRoute';
|
||||||
import { UserRole } from '@prisma/client';
|
import { UserRole } from '@prisma/client';
|
||||||
|
|
||||||
function PwaManager({ subs }) {
|
function PwaManager({ userId, subs }) {
|
||||||
//ToDo: for iOS, try to use apn? https://github.com/node-apn/node-apn/blob/master/doc/apn.markdown
|
//ToDo: for iOS, try to use apn? https://github.com/node-apn/node-apn/blob/master/doc/apn.markdown
|
||||||
const isSupported = () =>
|
const isSupported = () =>
|
||||||
'Notification' in window &&
|
'Notification' in window &&
|
||||||
@ -271,6 +271,37 @@ function PwaManager({ subs }) {
|
|||||||
{ action: 'close', title: 'Затвори', icon: '❌' }]
|
{ action: 'close', title: 'Затвори', icon: '❌' }]
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
await fetch('/api/notify', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
id: pub.id,
|
||||||
|
message: "Тестово съобщение",
|
||||||
|
title: "Това е тестово съобщение от https://sofia.mwitnessing.com",
|
||||||
|
actions: [
|
||||||
|
{ action: 'OK', title: 'OK', icon: '✅' },
|
||||||
|
{ action: 'close', title: 'Затвори', icon: '❌' }
|
||||||
|
]
|
||||||
|
// actions: [
|
||||||
|
// {
|
||||||
|
// title: 'Open URL',
|
||||||
|
// action: 'open_url',
|
||||||
|
// icon: '/images/open-url.png'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// title: 'Dismiss',
|
||||||
|
// action: 'dismiss',
|
||||||
|
// icon: '/images/dismiss.png'
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
*/
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// async function sendTestReminder(event: MouseEvent<HTMLButtonElement, MouseEvent>): Promise<void> {
|
// async function sendTestReminder(event: MouseEvent<HTMLButtonElement, MouseEvent>): Promise<void> {
|
||||||
@ -382,7 +413,7 @@ function PwaManager({ subs }) {
|
|||||||
>
|
>
|
||||||
Тестово уведомление
|
Тестово уведомление
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div >
|
||||||
{isAdmin &&
|
{isAdmin &&
|
||||||
<div>
|
<div>
|
||||||
{/* <button
|
{/* <button
|
||||||
@ -403,28 +434,31 @@ function PwaManager({ subs }) {
|
|||||||
</button> */}
|
</button> */}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
{notificationPermission !== "granted" && (
|
{
|
||||||
<button
|
notificationPermission !== "granted" && (
|
||||||
onClick={togglePushNotifications}
|
<button
|
||||||
className={`text-xs py-1 px-2 rounded-full focus:outline-none transition duration-150 ease-in-out ${notificationPermission === "denied" ? 'bg-red-500 hover:bg-red-700 text-white' : 'bg-green-500 hover:bg-green-700 text-white'
|
onClick={togglePushNotifications}
|
||||||
}`}
|
className={`text-xs py-1 px-2 rounded-full focus:outline-none transition duration-150 ease-in-out ${notificationPermission === "denied" ? 'bg-red-500 hover:bg-red-700 text-white' : 'bg-green-500 hover:bg-green-700 text-white'
|
||||||
>
|
}`}
|
||||||
{notificationPermission === "denied" ? 'Notifications Denied!' : 'Enable Notifications'}
|
>
|
||||||
</button>
|
{notificationPermission === "denied" ? 'Notifications Denied!' : 'Enable Notifications'}
|
||||||
)}
|
</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
{isAdmin && <div>
|
{
|
||||||
<div>
|
isAdmin && <div>
|
||||||
<a href="https://t.me/mwhitnessing_bot" className="inline-flex items-center ml-4" target="_blank">
|
<div>
|
||||||
<img src="/content/icons/telegram-svgrepo-com.svg" alt="Телеграм" width="32" height="32" className="align-middle" />
|
<a href="https://t.me/mwhitnessing_bot" className="inline-flex items-center ml-4" target="_blank">
|
||||||
<span className="align-middle">Телеграм</span>
|
<img src="/content/icons/telegram-svgrepo-com.svg" alt="Телеграм" width="32" height="32" className="align-middle" />
|
||||||
</a>
|
<span className="align-middle">Телеграм</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
<a href="/api/auth/apple-signin" className="inline-flex items-center ml-4 bg-gray-100 button" target="_blank">
|
<a href="/api/auth/apple-signin" className="inline-flex items-center ml-4 bg-gray-100 button" target="_blank">
|
||||||
<span className="align-middle">Apple sign-in</span>
|
<span className="align-middle">Apple sign-in</span>
|
||||||
</a>
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -22,7 +22,7 @@ const fetchConfig = async () => {
|
|||||||
return config.default;
|
return config.default;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function AvailabilityForm({ publisherId, existingItems, inline, onDone, date, cartEvent, datePicker = false }) {
|
export default function AvailabilityForm({ publisherId, existingItems, inline, onDone, date, cartEvent, datePicker = false, lockedBeforeDate }) {
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const urls = {
|
const urls = {
|
||||||
@ -31,14 +31,15 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o
|
|||||||
};
|
};
|
||||||
|
|
||||||
const id = parseInt(router.query.id);
|
const id = parseInt(router.query.id);
|
||||||
//coalsce existingItems to empty array
|
|
||||||
existingItems = existingItems || [];
|
const originalAvailabilities = existingItems || [];
|
||||||
|
|
||||||
const [editMode, setEditMode] = useState(existingItems.length > 0);
|
const [editMode, setEditMode] = useState(existingItems.length > 0);
|
||||||
const [publisher, setPublisher] = useState({ id: publisherId });
|
const [publisher, setPublisher] = useState({ id: publisherId });
|
||||||
const [day, setDay] = useState(new Date(date));
|
const [day, setDay] = useState(new Date(date));
|
||||||
const [canUpdate, setCanUpdate] = useState(true);
|
const [canUpdate, setCanUpdate] = useState(true);
|
||||||
|
|
||||||
|
|
||||||
const [timeSlots, setTimeSlots] = useState([]);
|
const [timeSlots, setTimeSlots] = useState([]);
|
||||||
const [availabilities, setAvailabilities] = useState(existingItems && existingItems.length > 0 ? existingItems : [{
|
const [availabilities, setAvailabilities] = useState(existingItems && existingItems.length > 0 ? existingItems : [{
|
||||||
publisherId: publisher.id,
|
publisherId: publisher.id,
|
||||||
@ -143,6 +144,35 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o
|
|||||||
setAvailabilities(avs);
|
setAvailabilities(avs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Handle repetition logic
|
||||||
|
// const parentAvailabilityId = avs[0].id;
|
||||||
|
// originalAvailabilities.forEach(async av => {
|
||||||
|
// if (av.repeatWeekly && av.startTime < lockedBeforeDate) {
|
||||||
|
// const newDate = av.startTime;
|
||||||
|
// while (newDate < lockedBeforeDate) {
|
||||||
|
// const newAvailability = {
|
||||||
|
// ...av,
|
||||||
|
// startTime: newDate,
|
||||||
|
// parentAvailability: { connect: { id: parentAvailabilityId } },
|
||||||
|
// publisher: { connect: { id: publisher.id } },
|
||||||
|
// dateOfEntry: new Date(),
|
||||||
|
// type: "OneTime"
|
||||||
|
// };
|
||||||
|
|
||||||
|
// delete newAvailability.id;
|
||||||
|
// delete newAvailability.title;
|
||||||
|
// delete newAvailability.date;
|
||||||
|
// delete newAvailability.publisherId
|
||||||
|
|
||||||
|
// await axiosInstance.post(urls.apiUrl, newAvailability);
|
||||||
|
// newDate.setDate(newDate.getDate() + 7); // Repeat weekly
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// console.log("Updated availability: ", av)
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
|
||||||
handleCompletion({ updated: true });
|
handleCompletion({ updated: true });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
alert("Нещо се обърка. Моля, опитайте отново по-късно.");
|
alert("Нещо се обърка. Моля, опитайте отново по-късно.");
|
||||||
@ -220,9 +250,9 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o
|
|||||||
availability.dateOfEntry = new Date();
|
availability.dateOfEntry = new Date();
|
||||||
}
|
}
|
||||||
|
|
||||||
function createAvailabilityFromGroup(group) {
|
function createAvailabilityFromGroup(group, publisherId) {
|
||||||
let availability = {
|
let availability = {
|
||||||
publisherId: publisher.id,
|
publisherId: publisherId,
|
||||||
dayofweek: common.getDayOfWeekNameEnEnumForDate(day),
|
dayofweek: common.getDayOfWeekNameEnEnumForDate(day),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -62,6 +62,28 @@ const AvCalendar = ({ publisherId, events, selectedDate, cartEvents, lastPublish
|
|||||||
}, []);
|
}, []);
|
||||||
//const isAdmin = ProtectedRoute.IsInRole(UserRole.ADMIN);
|
//const isAdmin = ProtectedRoute.IsInRole(UserRole.ADMIN);
|
||||||
|
|
||||||
|
//block dates between 1 and 18 august 2024
|
||||||
|
const blockedDates = [
|
||||||
|
new Date(2024, 7, 1),
|
||||||
|
new Date(2024, 7, 2),
|
||||||
|
new Date(2024, 7, 3),
|
||||||
|
new Date(2024, 7, 4),
|
||||||
|
new Date(2024, 7, 5),
|
||||||
|
new Date(2024, 7, 6),
|
||||||
|
new Date(2024, 7, 7),
|
||||||
|
new Date(2024, 7, 8),
|
||||||
|
new Date(2024, 7, 9),
|
||||||
|
new Date(2024, 7, 10),
|
||||||
|
new Date(2024, 7, 11),
|
||||||
|
new Date(2024, 7, 12),
|
||||||
|
new Date(2024, 7, 13),
|
||||||
|
new Date(2024, 7, 14),
|
||||||
|
new Date(2024, 7, 15),
|
||||||
|
new Date(2024, 7, 16),
|
||||||
|
new Date(2024, 7, 17),
|
||||||
|
new Date(2024, 7, 18),
|
||||||
|
];
|
||||||
|
|
||||||
const [date, setDate] = useState(new Date());
|
const [date, setDate] = useState(new Date());
|
||||||
//ToDo: see if we can optimize this
|
//ToDo: see if we can optimize this
|
||||||
const [evts, setEvents] = useState(events); // Existing events
|
const [evts, setEvents] = useState(events); // Existing events
|
||||||
@ -243,6 +265,11 @@ const AvCalendar = ({ publisherId, events, selectedDate, cartEvents, lastPublish
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (blockedDates[0] <= startdate && startdate <= blockedDates[blockedDates.length - 1]) {
|
||||||
|
toast.error(`Не можете да въвеждате предпочитания за ${common.getDateFormattedShort(startdate)}`, { autoClose: 5000 });
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Check if start and end are on the same day
|
// Check if start and end are on the same day
|
||||||
if (startdate.toDateString() !== enddate.toDateString()) {
|
if (startdate.toDateString() !== enddate.toDateString()) {
|
||||||
@ -539,6 +566,27 @@ const AvCalendar = ({ publisherId, events, selectedDate, cartEvents, lastPublish
|
|||||||
},
|
},
|
||||||
// ... other custom components
|
// ... other custom components
|
||||||
}}
|
}}
|
||||||
|
dayPropGetter={(date) => {
|
||||||
|
// Highlight the current day
|
||||||
|
// if (date.toDateString() === new Date().toDateString()) {
|
||||||
|
// return {
|
||||||
|
// style: {
|
||||||
|
// // white-500 from Tailwind CSS
|
||||||
|
// backgroundColor: '#f9fafb',
|
||||||
|
// color: 'white'
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
if (blockedDates[0] <= date && date <= blockedDates[blockedDates.length - 1]) {
|
||||||
|
return {
|
||||||
|
style: {
|
||||||
|
// red-100 from Tailwind CSS
|
||||||
|
backgroundColor: '#fee2e2',
|
||||||
|
color: 'white'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}}
|
||||||
eventPropGetter={(eventStyleGetter)}
|
eventPropGetter={(eventStyleGetter)}
|
||||||
date={date}
|
date={date}
|
||||||
showAllEvents={true}
|
showAllEvents={true}
|
||||||
@ -556,6 +604,7 @@ const AvCalendar = ({ publisherId, events, selectedDate, cartEvents, lastPublish
|
|||||||
onDone={handleDialogClose}
|
onDone={handleDialogClose}
|
||||||
inline={true}
|
inline={true}
|
||||||
cartEvent={cartEvent}
|
cartEvent={cartEvent}
|
||||||
|
lockedBeforeDate={editLockedBefore}
|
||||||
// Pass other props as needed
|
// Pass other props as needed
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -303,7 +303,8 @@ export default function PublisherForm({ item, me }) {
|
|||||||
{/* In-App notifications group */}
|
{/* In-App notifications group */}
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<h3 className="text-md font-semibold mb-2">Известия в приложението</h3>
|
<h3 className="text-md font-semibold mb-2">Известия в приложението</h3>
|
||||||
<PwaManager />
|
<PwaManager userId={publisher.userId || session.user.id} />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
|
189
components/publisher/PublisherShiftsModal.js
Normal file
189
components/publisher/PublisherShiftsModal.js
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
import React, { useEffect } from 'react';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import common from 'src/helpers/common';
|
||||||
|
import axiosInstance from 'src/axiosSecure';
|
||||||
|
|
||||||
|
const PublisherShiftsModal = ({ publisher, _shifts, onClose, date, onAssignmentChange }) => {
|
||||||
|
|
||||||
|
const [shifts, setShifts] = React.useState([..._shifts]);
|
||||||
|
//Refactor ToDo: show the whole month instead of just the current week by showing the shift start time in front of the rows, and show all shifts in the month from the first to the last week in the cell where we show one shift now
|
||||||
|
|
||||||
|
const monthInfo = common.getMonthDatesInfo(new Date(date));
|
||||||
|
const monthShifts = shifts.filter(shift => {
|
||||||
|
const shiftDate = new Date(shift.startTime);
|
||||||
|
return shiftDate > monthInfo.firstDay && shiftDate < monthInfo.lastDay;
|
||||||
|
});
|
||||||
|
const weekShifts = monthShifts.filter(shift => {
|
||||||
|
const shiftDate = new Date(shift.startTime);
|
||||||
|
return common.getStartOfWeek(date) <= shiftDate && shiftDate <= common.getEndOfWeek(date);
|
||||||
|
});
|
||||||
|
const dayShifts = weekShifts.map(shift => {
|
||||||
|
const isAvailable = publisher?.availabilities?.some(avail =>
|
||||||
|
avail.startTime <= shift.startTime && avail.endTime >= shift.endTime
|
||||||
|
);
|
||||||
|
let color = isAvailable ? getColorForShift(shift) : 'bg-gray-300';
|
||||||
|
if (shift.isFromPreviousMonth) {
|
||||||
|
color += ' border-l-4 border-orange-500 ';
|
||||||
|
}
|
||||||
|
if (shift.isFromPreviousAssignment) {
|
||||||
|
color += ' border-l-4 border-red-500 ';
|
||||||
|
}
|
||||||
|
return { ...shift, isAvailable, color };
|
||||||
|
}).reduce((acc, shift) => {
|
||||||
|
const dayIndex = new Date(shift.startTime).getDay();
|
||||||
|
acc[dayIndex] = acc[dayIndex] || [];
|
||||||
|
acc[dayIndex].push(shift);
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
console.log("dayShifts:", dayShifts);
|
||||||
|
|
||||||
|
const hasAssignment = (shiftId) => {
|
||||||
|
// return publisher.assignments.some(ass => ass.shift.id == shiftId);
|
||||||
|
return publisher.assignments?.some(ass => {
|
||||||
|
//console.log(`Comparing: ${ass.shift.id} to ${shiftId}: ${ass.shift.id === shiftId}`);
|
||||||
|
return ass.shift.id === shiftId;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleKeyDown = (event) => {
|
||||||
|
if (event.key === 'Escape') {
|
||||||
|
console.log('ESC: closing modal.');
|
||||||
|
onClose(); // Call the onClose function when ESC key is pressed
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add event listener
|
||||||
|
window.addEventListener('keydown', handleKeyDown);
|
||||||
|
|
||||||
|
// Remove event listener on cleanup
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('keydown', handleKeyDown);
|
||||||
|
};
|
||||||
|
}, [onClose]); // Include onClose in the dependency array
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="fixed top-0 left-0 w-full h-full flex items-center justify-center bg-black bg-opacity-50 z-50">
|
||||||
|
<div className="relative bg-white p-8 rounded-lg shadow-xl max-w-xl w-full h-auto overflow-y-auto">
|
||||||
|
<h2 className="text-xl font-semibold mb-4">График на <span title={publisher.email} className='publisher'>
|
||||||
|
<strong>{publisher.firstName} {publisher.lastName}</strong>
|
||||||
|
<span className="publisher-tooltip" onClick={common.copyToClipboard}>{publisher.email}</span>
|
||||||
|
</span> тази седмица:</h2>
|
||||||
|
|
||||||
|
{/* ... Display shifts in a calendar-like UI ... */}
|
||||||
|
<div className="grid grid-cols-6 gap-4 mb-4">
|
||||||
|
{Object.entries(dayShifts).map(([dayIndex, shiftsForDay]) => (
|
||||||
|
<div key={dayIndex} className="flex flex-col space-y-2 justify-end">
|
||||||
|
{/* Day header */}
|
||||||
|
<div className="text-center font-medium">{new Date(shiftsForDay[0].startTime).getDate()}-ти</div>
|
||||||
|
|
||||||
|
{shiftsForDay.map((shift, index) => {
|
||||||
|
const assignmentExists = hasAssignment(shift.id);
|
||||||
|
const availability = publisher.availabilities.find(avail =>
|
||||||
|
avail.startTime <= shift.startTime && avail.endTime >= shift.endTime
|
||||||
|
);
|
||||||
|
const isFromPrevMonth = availability && availability.isFromPreviousMonth;
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className={`text-sm text-white p-2 rounded-md ${isFromPrevMonth ? 'border-l-6 border-black-500' : ''} ${shift.color} ${assignmentExists ? 'border-2 border-blue-500' : ""} h-24 flex flex-col justify-center`}
|
||||||
|
>
|
||||||
|
{common.getTimeRange(shift.startTime, shift.endTime)} {shift.id}
|
||||||
|
|
||||||
|
{!assignmentExists && shift.isAvailable && (
|
||||||
|
<button onClick={() => { addAssignment(publisher, shift.id); }}
|
||||||
|
className="mt-2 bg-green-500 text-white p-1 rounded hover:bg-green-600 active:bg-green-700 focus:outline-none"
|
||||||
|
>
|
||||||
|
добави
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
{assignmentExists && (
|
||||||
|
<button onClick={() => { removeAssignment(publisher, shift.id) }} // Implement the removeAssignment function
|
||||||
|
className="mt-2 bg-red-500 text-white p-1 rounded hover:bg-red-600 active:bg-red-700 focus:outline-none"
|
||||||
|
>
|
||||||
|
махни
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Close button in the top right corner */}
|
||||||
|
<button
|
||||||
|
onClick={onClose}
|
||||||
|
className="absolute top-3 right-2 p-2 px-3 bg-red-500 text-white rounded-full hover:bg-red-600 active:bg-red-700 focus:outline-none"
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* <Link href={`/cart/publishers/edit/${publisher.id}`}
|
||||||
|
className="mt-2 bg-blue-500 text-white p-1 rounded hover:bg-blue-600 active:bg-blue-700 focus:outline-none">
|
||||||
|
<i className="fas fa-edit" />
|
||||||
|
</Link> */}
|
||||||
|
{/* Edit button in the top right corner, next to the close button */}
|
||||||
|
<Link href={`/cart/publishers/edit/${publisher.id}`} className="absolute top-3 right-12 p-2 bg-blue-500 text-white rounded-full hover:bg-blue-600 active:bg-blue-700 focus:outline-none">
|
||||||
|
<i className="fas fa-edit" />
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div >
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getColorForShift(shift) {
|
||||||
|
const assignedCount = shift.assignedCount || 0; // Assuming each shift has an assignedCount property
|
||||||
|
switch (assignedCount) {
|
||||||
|
case 0: return 'bg-blue-300';
|
||||||
|
case 1: return 'bg-green-300';
|
||||||
|
case 2: return 'bg-yellow-300';
|
||||||
|
case 3: return 'bg-orange-300';
|
||||||
|
case 4: return 'bg-red-200';
|
||||||
|
default: return 'bg-gray-300';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//ToDo: DRY - move to common
|
||||||
|
const addAssignment = async (publisher, shiftId) => {
|
||||||
|
try {
|
||||||
|
console.log(`calendar.idx: new assignment for publisher ${publisher.id} - ${publisher.firstName} ${publisher.lastName}`);
|
||||||
|
const newAssignment = {
|
||||||
|
publisher: { connect: { id: publisher.id } },
|
||||||
|
shift: { connect: { id: shiftId } },
|
||||||
|
isConfirmed: true
|
||||||
|
};
|
||||||
|
const { data } = await axiosInstance.post("/api/data/assignments", newAssignment);
|
||||||
|
|
||||||
|
// Update the 'publisher' property of the returned data with the full publisher object
|
||||||
|
data.publisher = publisher;
|
||||||
|
data.shift = shifts.find(shift => shift.id === shiftId);
|
||||||
|
publisher.assignments = [...publisher.assignments, data];
|
||||||
|
// handleAssignmentChange(publisher.id, 'add');
|
||||||
|
if (onAssignmentChange) { onAssignmentChange(publisher.id, 'add'); }
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error adding assignment:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const removeAssignment = async (publisher, shiftId) => {
|
||||||
|
try {
|
||||||
|
const assignment = publisher.assignments.find(ass => ass.shift.id === shiftId);
|
||||||
|
console.log(`calendar.idx: remove assignment for shift ${shiftId}`);
|
||||||
|
const { data } = await axiosInstance.delete(`/api/data/assignments/${assignment.id}`);
|
||||||
|
//remove from local assignments:
|
||||||
|
publisher.assignments = publisher.assignments.filter(a => a.id !== assignment.id)
|
||||||
|
//
|
||||||
|
// handleAssignmentChange(publisher.id, 'remove')
|
||||||
|
if (onAssignmentChange) {
|
||||||
|
onAssignmentChange(publisher.id, 'remove')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error removing assignment:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default PublisherShiftsModal;
|
@ -158,7 +158,7 @@ export default function ReportForm({ shiftId, existingItem, onDone }) {
|
|||||||
</option>
|
</option>
|
||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
<div className="mb-4">
|
{/* <div className="mb-4">
|
||||||
<label className="block text-gray-700 text-sm font-bold mb-2">
|
<label className="block text-gray-700 text-sm font-bold mb-2">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
@ -168,7 +168,7 @@ export default function ReportForm({ shiftId, existingItem, onDone }) {
|
|||||||
/>
|
/>
|
||||||
за целия ден
|
за целия ден
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div> */}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
|
@ -62,8 +62,8 @@ const SurveyForm: React.FC<SurveyFormProps> = ({ existingItem }) => {
|
|||||||
...existingItem,
|
...existingItem,
|
||||||
content: existingItem?.content || "Нова анкета",
|
content: existingItem?.content || "Нова анкета",
|
||||||
answers: existingItem?.answers.split(",") || [],
|
answers: existingItem?.answers.split(",") || [],
|
||||||
publicFrom: existingItem?.publicFrom ? dayjs(existingItem.publicFrom).toISOString() : new Date().toISOString(),
|
publicFrom: existingItem?.publicFrom ? dayjs(existingItem.publicFrom).toISOString() : '',
|
||||||
publicUntil: existingItem?.publicUntil ? dayjs(existingItem.publicUntil).toISOString() : new Date().toISOString(),
|
publicUntil: existingItem?.publicUntil ? dayjs(existingItem.publicUntil).toISOString() : null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ const SurveyForm: React.FC<SurveyFormProps> = ({ existingItem }) => {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//get all publisherIds and create a message for each
|
//get all publisherIds and create a message for each
|
||||||
const messages = pubs.data.map(pub => {
|
const messages = pubs.map(pub => {
|
||||||
return {
|
return {
|
||||||
publisherId: pub.id,
|
publisherId: pub.id,
|
||||||
content: JSON.stringify({ message: item.content, options: item.answers }),
|
content: JSON.stringify({ message: item.content, options: item.answers }),
|
||||||
@ -211,7 +211,7 @@ const SurveyForm: React.FC<SurveyFormProps> = ({ existingItem }) => {
|
|||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
id,
|
id,
|
||||||
title: 'Нямаме отговор',
|
title: 'Напомняне',
|
||||||
message: `${message}`,
|
message: `${message}`,
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@ -236,13 +236,16 @@ const SurveyForm: React.FC<SurveyFormProps> = ({ existingItem }) => {
|
|||||||
<label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="date">
|
<label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="date">
|
||||||
Видима от
|
Видима от
|
||||||
</label>
|
</label>
|
||||||
<DatePicker className="textbox form-input px-4 py-2 rounded" name="publicFrom" onChange={(newDate) => handleDateChange('publicFrom', newDate)} value={dayjs(item?.publicFrom)} />
|
<DatePicker className="textbox form-input px-4 py-2 rounded" name="publicFrom" onChange={(newDate) => handleDateChange('publicFrom', newDate)}
|
||||||
|
value={item && item.publicFrom ? dayjs(item.publicFrom) : null} />
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="date">
|
<label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="date">
|
||||||
Видима до
|
Видима до
|
||||||
</label>
|
</label>
|
||||||
<DatePicker className="textbox form-input px-4 py-2 rounded" name="publicUntil" onChange={(newDate) => handleDateChange('publicUntil', newDate)} value={dayjs(item?.publicUntil)} />
|
<DatePicker className="textbox form-input px-4 py-2 rounded" name="publicUntil" onChange={(newDate) => handleDateChange('publicUntil', newDate)}
|
||||||
|
value={item && item.publicUntil ? dayjs(item.publicUntil) : null}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="content">
|
<label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="content">
|
||||||
|
577
package-lock.json
generated
577
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "smws",
|
"name": "smws",
|
||||||
"version": "1.2.4",
|
"version": "1.3.5",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "smws",
|
"name": "smws",
|
||||||
"version": "1.2.4",
|
"version": "1.3.5",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@auth/prisma-adapter": "^1.4.0",
|
"@auth/prisma-adapter": "^1.4.0",
|
||||||
"@emotion/react": "^11.11.3",
|
"@emotion/react": "^11.11.3",
|
||||||
@ -16,7 +16,7 @@
|
|||||||
"@mui/material": "^5.15.10",
|
"@mui/material": "^5.15.10",
|
||||||
"@mui/x-date-pickers": "^6.19.4",
|
"@mui/x-date-pickers": "^6.19.4",
|
||||||
"@premieroctet/next-crud": "^3.0.0",
|
"@premieroctet/next-crud": "^3.0.0",
|
||||||
"@prisma/client": "^5.15.0",
|
"@prisma/client": "^5.19.1",
|
||||||
"@react-pdf/renderer": "^3.3.8",
|
"@react-pdf/renderer": "^3.3.8",
|
||||||
"@tailwindcss/forms": "^0.5.7",
|
"@tailwindcss/forms": "^0.5.7",
|
||||||
"@types/multer": "^1.4.11",
|
"@types/multer": "^1.4.11",
|
||||||
@ -93,14 +93,14 @@
|
|||||||
"winston-daily-rotate-file": "^5.0.0",
|
"winston-daily-rotate-file": "^5.0.0",
|
||||||
"workbox-webpack-plugin": "^7.1.0",
|
"workbox-webpack-plugin": "^7.1.0",
|
||||||
"xlsx": "https://cdn.sheetjs.com/xlsx-0.19.1/xlsx-0.19.1.tgz",
|
"xlsx": "https://cdn.sheetjs.com/xlsx-0.19.1/xlsx-0.19.1.tgz",
|
||||||
"xlsx-style": "^0.8.13",
|
"xlsx-js-style": "^1.2.0",
|
||||||
"xml-js": "^1.6.11",
|
"xml-js": "^1.6.11",
|
||||||
"xml2js": "^0.6.2"
|
"xml2js": "^0.6.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"depcheck": "^1.4.7",
|
"depcheck": "^1.4.7",
|
||||||
"prisma": "^5.15.0"
|
"prisma": "^5.19.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@alloc/quick-lru": {
|
"node_modules/@alloc/quick-lru": {
|
||||||
@ -3239,14 +3239,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/env": {
|
"node_modules/@next/env": {
|
||||||
"version": "14.1.0",
|
"version": "14.2.10",
|
||||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.10.tgz",
|
||||||
"integrity": "sha512-Py8zIo+02ht82brwwhTg36iogzFqGLPXlRGKQw5s+qP/kMNc4MAyDeEwBKDijk6zTIbegEgu8Qy7C1LboslQAw=="
|
"integrity": "sha512-dZIu93Bf5LUtluBXIv4woQw2cZVZ2DJTjax5/5DOs3lzEOeKLy7GxRSr4caK9/SCPdaW6bCgpye6+n4Dh9oJPw=="
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-darwin-arm64": {
|
"node_modules/@next/swc-darwin-arm64": {
|
||||||
"version": "14.1.0",
|
"version": "14.2.10",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.10.tgz",
|
||||||
"integrity": "sha512-nUDn7TOGcIeyQni6lZHfzNoo9S0euXnu0jhsbMOmMJUBfgsnESdjN97kM7cBqQxZa8L/bM9om/S5/1dzCrW6wQ==",
|
"integrity": "sha512-V3z10NV+cvMAfxQUMhKgfQnPbjw+Ew3cnr64b0lr8MDiBJs3eLnM6RpGC46nhfMZsiXgQngCJKWGTC/yDcgrDQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -3259,9 +3259,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-darwin-x64": {
|
"node_modules/@next/swc-darwin-x64": {
|
||||||
"version": "14.1.0",
|
"version": "14.2.10",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.10.tgz",
|
||||||
"integrity": "sha512-1jgudN5haWxiAl3O1ljUS2GfupPmcftu2RYJqZiMJmmbBT5M1XDffjUtRUzP4W3cBHsrvkfOFdQ71hAreNQP6g==",
|
"integrity": "sha512-Y0TC+FXbFUQ2MQgimJ/7Ina2mXIKhE7F+GUe1SgnzRmwFY3hX2z8nyVCxE82I2RicspdkZnSWMn4oTjIKz4uzA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -3274,9 +3274,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-linux-arm64-gnu": {
|
"node_modules/@next/swc-linux-arm64-gnu": {
|
||||||
"version": "14.1.0",
|
"version": "14.2.10",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.10.tgz",
|
||||||
"integrity": "sha512-RHo7Tcj+jllXUbK7xk2NyIDod3YcCPDZxj1WLIYxd709BQ7WuRYl3OWUNG+WUfqeQBds6kvZYlc42NJJTNi4tQ==",
|
"integrity": "sha512-ZfQ7yOy5zyskSj9rFpa0Yd7gkrBnJTkYVSya95hX3zeBG9E55Z6OTNPn1j2BTFWvOVVj65C3T+qsjOyVI9DQpA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -3289,9 +3289,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-linux-arm64-musl": {
|
"node_modules/@next/swc-linux-arm64-musl": {
|
||||||
"version": "14.1.0",
|
"version": "14.2.10",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.10.tgz",
|
||||||
"integrity": "sha512-v6kP8sHYxjO8RwHmWMJSq7VZP2nYCkRVQ0qolh2l6xroe9QjbgV8siTbduED4u0hlk0+tjS6/Tuy4n5XCp+l6g==",
|
"integrity": "sha512-n2i5o3y2jpBfXFRxDREr342BGIQCJbdAUi/K4q6Env3aSx8erM9VuKXHw5KNROK9ejFSPf0LhoSkU/ZiNdacpQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -3304,9 +3304,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-linux-x64-gnu": {
|
"node_modules/@next/swc-linux-x64-gnu": {
|
||||||
"version": "14.1.0",
|
"version": "14.2.10",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.10.tgz",
|
||||||
"integrity": "sha512-zJ2pnoFYB1F4vmEVlb/eSe+VH679zT1VdXlZKX+pE66grOgjmKJHKacf82g/sWE4MQ4Rk2FMBCRnX+l6/TVYzQ==",
|
"integrity": "sha512-GXvajAWh2woTT0GKEDlkVhFNxhJS/XdDmrVHrPOA83pLzlGPQnixqxD8u3bBB9oATBKB//5e4vpACnx5Vaxdqg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -3319,9 +3319,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-linux-x64-musl": {
|
"node_modules/@next/swc-linux-x64-musl": {
|
||||||
"version": "14.1.0",
|
"version": "14.2.10",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.10.tgz",
|
||||||
"integrity": "sha512-rbaIYFt2X9YZBSbH/CwGAjbBG2/MrACCVu2X0+kSykHzHnYH5FjHxwXLkcoJ10cX0aWCEynpu+rP76x0914atg==",
|
"integrity": "sha512-opFFN5B0SnO+HTz4Wq4HaylXGFV+iHrVxd3YvREUX9K+xfc4ePbRrxqOuPOFjtSuiVouwe6uLeDtabjEIbkmDA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -3334,9 +3334,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-win32-arm64-msvc": {
|
"node_modules/@next/swc-win32-arm64-msvc": {
|
||||||
"version": "14.1.0",
|
"version": "14.2.10",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.10.tgz",
|
||||||
"integrity": "sha512-o1N5TsYc8f/HpGt39OUQpQ9AKIGApd3QLueu7hXk//2xq5Z9OxmV6sQfNp8C7qYmiOlHYODOGqNNa0e9jvchGQ==",
|
"integrity": "sha512-9NUzZuR8WiXTvv+EiU/MXdcQ1XUvFixbLIMNQiVHuzs7ZIFrJDLJDaOF1KaqttoTujpcxljM/RNAOmw1GhPPQQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -3349,9 +3349,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-win32-ia32-msvc": {
|
"node_modules/@next/swc-win32-ia32-msvc": {
|
||||||
"version": "14.1.0",
|
"version": "14.2.10",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.10.tgz",
|
||||||
"integrity": "sha512-XXIuB1DBRCFwNO6EEzCTMHT5pauwaSj4SWs7CYnME57eaReAKBXCnkUE80p/pAZcewm7hs+vGvNqDPacEXHVkw==",
|
"integrity": "sha512-fr3aEbSd1GeW3YUMBkWAu4hcdjZ6g4NBl1uku4gAn661tcxd1bHs1THWYzdsbTRLcCKLjrDZlNp6j2HTfrw+Bg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
@ -3364,9 +3364,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-win32-x64-msvc": {
|
"node_modules/@next/swc-win32-x64-msvc": {
|
||||||
"version": "14.1.0",
|
"version": "14.2.10",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.10.tgz",
|
||||||
"integrity": "sha512-9WEbVRRAqJ3YFVqEZIxUqkiO8l1nool1LmNxygr5HWF8AcSYsEpneUDhmjUVJEzO2A04+oPtZdombzzPPkTtgg==",
|
"integrity": "sha512-UjeVoRGKNL2zfbcQ6fscmgjBAS/inHBh63mjIlfPg/NG8Yn2ztqylXt5qilYb6hoHIwaU2ogHknHWWmahJjgZQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -3915,9 +3915,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@prisma/client": {
|
"node_modules/@prisma/client": {
|
||||||
"version": "5.15.0",
|
"version": "5.19.1",
|
||||||
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.19.1.tgz",
|
||||||
"integrity": "sha512-wPTeTjbd2Q0abOeffN7zCDCbkp9C9cF+e9HPiI64lmpehyq2TepgXE+sY7FXr7Rhbb21prLMnhXX27/E11V09w==",
|
"integrity": "sha512-x30GFguInsgt+4z5I4WbkZP2CGpotJMUXy+Gl/aaUjHn2o1DnLYNTA+q9XdYmAQZM8fIIkvUiA2NpgosM3fneg==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16.13"
|
"node": ">=16.13"
|
||||||
@ -3932,39 +3932,39 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@prisma/debug": {
|
"node_modules/@prisma/debug": {
|
||||||
"version": "5.15.0",
|
"version": "5.19.1",
|
||||||
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.19.1.tgz",
|
||||||
"integrity": "sha512-QpEAOjieLPc/4sMny/WrWqtpIAmBYsgqwWlWwIctqZO0AbhQ9QcT6x2Ut3ojbDo/pFRCCA1Z1+xm2MUy7fAkZA==",
|
"integrity": "sha512-lAG6A6QnG2AskAukIEucYJZxxcSqKsMK74ZFVfCTOM/7UiyJQi48v6TQ47d6qKG3LbMslqOvnTX25dj/qvclGg==",
|
||||||
"devOptional": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/@prisma/engines": {
|
"node_modules/@prisma/engines": {
|
||||||
"version": "5.15.0",
|
"version": "5.19.1",
|
||||||
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.19.1.tgz",
|
||||||
"integrity": "sha512-hXL5Sn9hh/ZpRKWiyPA5GbvF3laqBHKt6Vo70hYqqOhh5e0ZXDzHcdmxNvOefEFeqxra2DMz2hNbFoPvqrVe1w==",
|
"integrity": "sha512-kR/PoxZDrfUmbbXqqb8SlBBgCjvGaJYMCOe189PEYzq9rKqitQ2fvT/VJ8PDSe8tTNxhc2KzsCfCAL+Iwm/7Cg==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@prisma/debug": "5.15.0",
|
"@prisma/debug": "5.19.1",
|
||||||
"@prisma/engines-version": "5.15.0-29.12e25d8d06f6ea5a0252864dd9a03b1bb51f3022",
|
"@prisma/engines-version": "5.19.1-2.69d742ee20b815d88e17e54db4a2a7a3b30324e3",
|
||||||
"@prisma/fetch-engine": "5.15.0",
|
"@prisma/fetch-engine": "5.19.1",
|
||||||
"@prisma/get-platform": "5.15.0"
|
"@prisma/get-platform": "5.19.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@prisma/engines-version": {
|
"node_modules/@prisma/engines-version": {
|
||||||
"version": "5.15.0-29.12e25d8d06f6ea5a0252864dd9a03b1bb51f3022",
|
"version": "5.19.1-2.69d742ee20b815d88e17e54db4a2a7a3b30324e3",
|
||||||
"resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.15.0-29.12e25d8d06f6ea5a0252864dd9a03b1bb51f3022.tgz",
|
"resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.19.1-2.69d742ee20b815d88e17e54db4a2a7a3b30324e3.tgz",
|
||||||
"integrity": "sha512-3BEgZ41Qb4oWHz9kZNofToRvNeS4LZYaT9pienR1gWkjhky6t6K1NyeWNBkqSj2llgraUNbgMOCQPY4f7Qp5wA==",
|
"integrity": "sha512-xR6rt+z5LnNqTP5BBc+8+ySgf4WNMimOKXRn6xfNRDSpHvbOEmd7+qAOmzCrddEc4Cp8nFC0txU14dstjH7FXA==",
|
||||||
"devOptional": true
|
"devOptional": true
|
||||||
},
|
},
|
||||||
"node_modules/@prisma/fetch-engine": {
|
"node_modules/@prisma/fetch-engine": {
|
||||||
"version": "5.15.0",
|
"version": "5.19.1",
|
||||||
"resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.19.1.tgz",
|
||||||
"integrity": "sha512-z6AY5yyXxc20Klj7wwnfGP0iIUkVKzybqapT02zLYR/nf9ynaeN8bq73WRmi1TkLYn+DJ5Qy+JGu7hBf1pE78A==",
|
"integrity": "sha512-pCq74rtlOVJfn4pLmdJj+eI4P7w2dugOnnTXpRilP/6n5b2aZiA4ulJlE0ddCbTPkfHmOL9BfaRgA8o+1rfdHw==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@prisma/debug": "5.15.0",
|
"@prisma/debug": "5.19.1",
|
||||||
"@prisma/engines-version": "5.15.0-29.12e25d8d06f6ea5a0252864dd9a03b1bb51f3022",
|
"@prisma/engines-version": "5.19.1-2.69d742ee20b815d88e17e54db4a2a7a3b30324e3",
|
||||||
"@prisma/get-platform": "5.15.0"
|
"@prisma/get-platform": "5.19.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@prisma/generator-helper": {
|
"node_modules/@prisma/generator-helper": {
|
||||||
@ -3981,12 +3981,12 @@
|
|||||||
"integrity": "sha512-tZ+MOjWlVvz1kOEhNYMa4QUGURY+kgOUBqLHYIV8jmCsMuvA1tWcn7qtIMLzYWCbDcQT4ZS8xDgK0R2gl6/0wA=="
|
"integrity": "sha512-tZ+MOjWlVvz1kOEhNYMa4QUGURY+kgOUBqLHYIV8jmCsMuvA1tWcn7qtIMLzYWCbDcQT4ZS8xDgK0R2gl6/0wA=="
|
||||||
},
|
},
|
||||||
"node_modules/@prisma/get-platform": {
|
"node_modules/@prisma/get-platform": {
|
||||||
"version": "5.15.0",
|
"version": "5.19.1",
|
||||||
"resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.19.1.tgz",
|
||||||
"integrity": "sha512-1GULDkW4+/VQb73vihxCBSc4Chc2x88MA+O40tcZFjmBzG4/fF44PaXFxUqKSFltxU9L9GIMLhh0Gfkk/pUbtg==",
|
"integrity": "sha512-sCeoJ+7yt0UjnR+AXZL7vXlg5eNxaFOwC23h0KvW1YIXUoa7+W2ZcAUhoEQBmJTW4GrFqCuZ8YSP0mkDa4k3Zg==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@prisma/debug": "5.15.0"
|
"@prisma/debug": "5.19.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@prisma/internals": {
|
"node_modules/@prisma/internals": {
|
||||||
@ -4366,6 +4366,11 @@
|
|||||||
"sourcemap-codec": "^1.4.8"
|
"sourcemap-codec": "^1.4.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@swc/counter": {
|
||||||
|
"version": "0.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
|
||||||
|
"integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="
|
||||||
|
},
|
||||||
"node_modules/@swc/helpers": {
|
"node_modules/@swc/helpers": {
|
||||||
"version": "0.4.36",
|
"version": "0.4.36",
|
||||||
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.36.tgz",
|
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.36.tgz",
|
||||||
@ -4443,26 +4448,6 @@
|
|||||||
"@types/ms": "*"
|
"@types/ms": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/eslint": {
|
|
||||||
"version": "8.56.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.7.tgz",
|
|
||||||
"integrity": "sha512-SjDvI/x3zsZnOkYZ3lCt9lOZWZLB2jIlNKz+LBgCtDurK0JZcwucxYHn1w2BJkD34dgX9Tjnak0txtq4WTggEA==",
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@types/estree": "*",
|
|
||||||
"@types/json-schema": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/eslint-scope": {
|
|
||||||
"version": "3.7.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
|
|
||||||
"integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@types/eslint": "*",
|
|
||||||
"@types/estree": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/estree": {
|
"node_modules/@types/estree": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
|
||||||
@ -4939,10 +4924,10 @@
|
|||||||
"node": ">=0.4.0"
|
"node": ">=0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/acorn-import-assertions": {
|
"node_modules/acorn-import-attributes": {
|
||||||
"version": "1.9.0",
|
"version": "1.9.5",
|
||||||
"resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz",
|
||||||
"integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
|
"integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"acorn": "^8"
|
"acorn": "^8"
|
||||||
@ -5396,11 +5381,11 @@
|
|||||||
"integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg=="
|
"integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg=="
|
||||||
},
|
},
|
||||||
"node_modules/axios": {
|
"node_modules/axios": {
|
||||||
"version": "1.6.7",
|
"version": "1.7.7",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
|
||||||
"integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==",
|
"integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"follow-redirects": "^1.15.4",
|
"follow-redirects": "^1.15.6",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
"proxy-from-env": "^1.1.0"
|
"proxy-from-env": "^1.1.0"
|
||||||
}
|
}
|
||||||
@ -5617,20 +5602,20 @@
|
|||||||
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
|
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
|
||||||
},
|
},
|
||||||
"node_modules/body-parser": {
|
"node_modules/body-parser": {
|
||||||
"version": "1.20.1",
|
"version": "1.20.3",
|
||||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
|
||||||
"integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
|
"integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bytes": "3.1.2",
|
"bytes": "3.1.2",
|
||||||
"content-type": "~1.0.4",
|
"content-type": "~1.0.5",
|
||||||
"debug": "2.6.9",
|
"debug": "2.6.9",
|
||||||
"depd": "2.0.0",
|
"depd": "2.0.0",
|
||||||
"destroy": "1.2.0",
|
"destroy": "1.2.0",
|
||||||
"http-errors": "2.0.0",
|
"http-errors": "2.0.0",
|
||||||
"iconv-lite": "0.4.24",
|
"iconv-lite": "0.4.24",
|
||||||
"on-finished": "2.4.1",
|
"on-finished": "2.4.1",
|
||||||
"qs": "6.11.0",
|
"qs": "6.13.0",
|
||||||
"raw-body": "2.5.1",
|
"raw-body": "2.5.2",
|
||||||
"type-is": "~1.6.18",
|
"type-is": "~1.6.18",
|
||||||
"unpipe": "1.0.0"
|
"unpipe": "1.0.0"
|
||||||
},
|
},
|
||||||
@ -5639,20 +5624,6 @@
|
|||||||
"npm": "1.2.8000 || >= 1.4.16"
|
"npm": "1.2.8000 || >= 1.4.16"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/body-parser/node_modules/qs": {
|
|
||||||
"version": "6.11.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
|
|
||||||
"integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
|
|
||||||
"dependencies": {
|
|
||||||
"side-channel": "^1.0.4"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.6"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
@ -5663,11 +5634,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/braces": {
|
"node_modules/braces": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fill-range": "^7.0.1"
|
"fill-range": "^7.1.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
@ -5878,9 +5849,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001588",
|
"version": "1.0.30001651",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001588.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz",
|
||||||
"integrity": "sha512-+hVY9jE44uKLkH0SrUTqxjxqNTOWHsbnQDIKjwkZ3lNTzUUVdBLBGXtj/q5Mp5u98r3droaZAewQuEDzjQdZlQ==",
|
"integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@ -7284,9 +7255,9 @@
|
|||||||
"integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="
|
"integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="
|
||||||
},
|
},
|
||||||
"node_modules/encodeurl": {
|
"node_modules/encodeurl": {
|
||||||
"version": "1.0.2",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
|
||||||
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
|
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
@ -7323,9 +7294,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/enhanced-resolve": {
|
"node_modules/enhanced-resolve": {
|
||||||
"version": "5.16.0",
|
"version": "5.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz",
|
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz",
|
||||||
"integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==",
|
"integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"graceful-fs": "^4.2.4",
|
"graceful-fs": "^4.2.4",
|
||||||
@ -7697,6 +7668,14 @@
|
|||||||
"url": "https://github.com/sindresorhus/execa?sponsor=1"
|
"url": "https://github.com/sindresorhus/execa?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/exit-on-epipe": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/expand-tilde": {
|
"node_modules/expand-tilde": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
|
||||||
@ -7710,36 +7689,36 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/express": {
|
"node_modules/express": {
|
||||||
"version": "4.18.2",
|
"version": "4.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
|
"resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz",
|
||||||
"integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
|
"integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"accepts": "~1.3.8",
|
"accepts": "~1.3.8",
|
||||||
"array-flatten": "1.1.1",
|
"array-flatten": "1.1.1",
|
||||||
"body-parser": "1.20.1",
|
"body-parser": "1.20.3",
|
||||||
"content-disposition": "0.5.4",
|
"content-disposition": "0.5.4",
|
||||||
"content-type": "~1.0.4",
|
"content-type": "~1.0.4",
|
||||||
"cookie": "0.5.0",
|
"cookie": "0.6.0",
|
||||||
"cookie-signature": "1.0.6",
|
"cookie-signature": "1.0.6",
|
||||||
"debug": "2.6.9",
|
"debug": "2.6.9",
|
||||||
"depd": "2.0.0",
|
"depd": "2.0.0",
|
||||||
"encodeurl": "~1.0.2",
|
"encodeurl": "~2.0.0",
|
||||||
"escape-html": "~1.0.3",
|
"escape-html": "~1.0.3",
|
||||||
"etag": "~1.8.1",
|
"etag": "~1.8.1",
|
||||||
"finalhandler": "1.2.0",
|
"finalhandler": "1.3.1",
|
||||||
"fresh": "0.5.2",
|
"fresh": "0.5.2",
|
||||||
"http-errors": "2.0.0",
|
"http-errors": "2.0.0",
|
||||||
"merge-descriptors": "1.0.1",
|
"merge-descriptors": "1.0.3",
|
||||||
"methods": "~1.1.2",
|
"methods": "~1.1.2",
|
||||||
"on-finished": "2.4.1",
|
"on-finished": "2.4.1",
|
||||||
"parseurl": "~1.3.3",
|
"parseurl": "~1.3.3",
|
||||||
"path-to-regexp": "0.1.7",
|
"path-to-regexp": "0.1.10",
|
||||||
"proxy-addr": "~2.0.7",
|
"proxy-addr": "~2.0.7",
|
||||||
"qs": "6.11.0",
|
"qs": "6.13.0",
|
||||||
"range-parser": "~1.2.1",
|
"range-parser": "~1.2.1",
|
||||||
"safe-buffer": "5.2.1",
|
"safe-buffer": "5.2.1",
|
||||||
"send": "0.18.0",
|
"send": "0.19.0",
|
||||||
"serve-static": "1.15.0",
|
"serve-static": "1.16.2",
|
||||||
"setprototypeof": "1.2.0",
|
"setprototypeof": "1.2.0",
|
||||||
"statuses": "2.0.1",
|
"statuses": "2.0.1",
|
||||||
"type-is": "~1.6.18",
|
"type-is": "~1.6.18",
|
||||||
@ -7768,32 +7747,10 @@
|
|||||||
"resolved": "https://registry.npmjs.org/express-unless/-/express-unless-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/express-unless/-/express-unless-2.1.3.tgz",
|
||||||
"integrity": "sha512-wj4tLMyCVYuIIKHGt0FhCtIViBcwzWejX0EjNxveAa6dG+0XBCQhMbx+PnkLkFCxLC69qoFrxds4pIyL88inaQ=="
|
"integrity": "sha512-wj4tLMyCVYuIIKHGt0FhCtIViBcwzWejX0EjNxveAa6dG+0XBCQhMbx+PnkLkFCxLC69qoFrxds4pIyL88inaQ=="
|
||||||
},
|
},
|
||||||
"node_modules/express/node_modules/cookie": {
|
|
||||||
"version": "0.5.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
|
|
||||||
"integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/express/node_modules/path-to-regexp": {
|
"node_modules/express/node_modules/path-to-regexp": {
|
||||||
"version": "0.1.7",
|
"version": "0.1.10",
|
||||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz",
|
||||||
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
|
"integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w=="
|
||||||
},
|
|
||||||
"node_modules/express/node_modules/qs": {
|
|
||||||
"version": "6.11.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
|
|
||||||
"integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
|
|
||||||
"dependencies": {
|
|
||||||
"side-channel": "^1.0.4"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.6"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"node_modules/extend": {
|
"node_modules/extend": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
@ -7877,6 +7834,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz",
|
||||||
"integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw=="
|
"integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/fflate": {
|
||||||
|
"version": "0.3.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.3.11.tgz",
|
||||||
|
"integrity": "sha512-Rr5QlUeGN1mbOHlaqcSYMKVpPbgLy0AWT/W0EHxA6NGI12yO1jpoui2zBBvU2G824ltM6Ut8BFgfHSBGfkmS0A=="
|
||||||
|
},
|
||||||
"node_modules/file-stream-rotator": {
|
"node_modules/file-stream-rotator": {
|
||||||
"version": "0.6.1",
|
"version": "0.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.6.1.tgz",
|
||||||
@ -7921,9 +7883,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fill-range": {
|
"node_modules/fill-range": {
|
||||||
"version": "7.0.1",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"to-regex-range": "^5.0.1"
|
"to-regex-range": "^5.0.1"
|
||||||
},
|
},
|
||||||
@ -7932,12 +7894,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/finalhandler": {
|
"node_modules/finalhandler": {
|
||||||
"version": "1.2.0",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
|
||||||
"integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
|
"integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": "2.6.9",
|
"debug": "2.6.9",
|
||||||
"encodeurl": "~1.0.2",
|
"encodeurl": "~2.0.0",
|
||||||
"escape-html": "~1.0.3",
|
"escape-html": "~1.0.3",
|
||||||
"on-finished": "2.4.1",
|
"on-finished": "2.4.1",
|
||||||
"parseurl": "~1.3.3",
|
"parseurl": "~1.3.3",
|
||||||
@ -8006,9 +7968,9 @@
|
|||||||
"integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="
|
"integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="
|
||||||
},
|
},
|
||||||
"node_modules/follow-redirects": {
|
"node_modules/follow-redirects": {
|
||||||
"version": "1.15.5",
|
"version": "1.15.9",
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz",
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
|
||||||
"integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==",
|
"integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@ -10643,9 +10605,12 @@
|
|||||||
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
|
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
|
||||||
},
|
},
|
||||||
"node_modules/merge-descriptors": {
|
"node_modules/merge-descriptors": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
|
||||||
"integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
|
"integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"node_modules/merge-stream": {
|
"node_modules/merge-stream": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
@ -10669,11 +10634,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/micromatch": {
|
"node_modules/micromatch": {
|
||||||
"version": "4.0.5",
|
"version": "4.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||||
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
|
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"braces": "^3.0.2",
|
"braces": "^3.0.3",
|
||||||
"picomatch": "^2.3.1"
|
"picomatch": "^2.3.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -10945,12 +10910,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/next": {
|
"node_modules/next": {
|
||||||
"version": "14.1.0",
|
"version": "14.2.10",
|
||||||
"resolved": "https://registry.npmjs.org/next/-/next-14.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/next/-/next-14.2.10.tgz",
|
||||||
"integrity": "sha512-wlzrsbfeSU48YQBjZhDzOwhWhGsy+uQycR8bHAOt1LY1bn3zZEcDyHQOEoN3aWzQ8LHCAJ1nqrWCc9XF2+O45Q==",
|
"integrity": "sha512-sDDExXnh33cY3RkS9JuFEKaS4HmlWmDKP1VJioucCG6z5KuA008DPsDZOzi8UfqEk3Ii+2NCQSJrfbEWtZZfww==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@next/env": "14.1.0",
|
"@next/env": "14.2.10",
|
||||||
"@swc/helpers": "0.5.2",
|
"@swc/helpers": "0.5.5",
|
||||||
"busboy": "1.6.0",
|
"busboy": "1.6.0",
|
||||||
"caniuse-lite": "^1.0.30001579",
|
"caniuse-lite": "^1.0.30001579",
|
||||||
"graceful-fs": "^4.2.11",
|
"graceful-fs": "^4.2.11",
|
||||||
@ -10964,18 +10929,19 @@
|
|||||||
"node": ">=18.17.0"
|
"node": ">=18.17.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@next/swc-darwin-arm64": "14.1.0",
|
"@next/swc-darwin-arm64": "14.2.10",
|
||||||
"@next/swc-darwin-x64": "14.1.0",
|
"@next/swc-darwin-x64": "14.2.10",
|
||||||
"@next/swc-linux-arm64-gnu": "14.1.0",
|
"@next/swc-linux-arm64-gnu": "14.2.10",
|
||||||
"@next/swc-linux-arm64-musl": "14.1.0",
|
"@next/swc-linux-arm64-musl": "14.2.10",
|
||||||
"@next/swc-linux-x64-gnu": "14.1.0",
|
"@next/swc-linux-x64-gnu": "14.2.10",
|
||||||
"@next/swc-linux-x64-musl": "14.1.0",
|
"@next/swc-linux-x64-musl": "14.2.10",
|
||||||
"@next/swc-win32-arm64-msvc": "14.1.0",
|
"@next/swc-win32-arm64-msvc": "14.2.10",
|
||||||
"@next/swc-win32-ia32-msvc": "14.1.0",
|
"@next/swc-win32-ia32-msvc": "14.2.10",
|
||||||
"@next/swc-win32-x64-msvc": "14.1.0"
|
"@next/swc-win32-x64-msvc": "14.2.10"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@opentelemetry/api": "^1.1.0",
|
"@opentelemetry/api": "^1.1.0",
|
||||||
|
"@playwright/test": "^1.41.2",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"sass": "^1.3.0"
|
"sass": "^1.3.0"
|
||||||
@ -10984,6 +10950,9 @@
|
|||||||
"@opentelemetry/api": {
|
"@opentelemetry/api": {
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
"@playwright/test": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"sass": {
|
"sass": {
|
||||||
"optional": true
|
"optional": true
|
||||||
}
|
}
|
||||||
@ -11025,9 +10994,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/next-auth/node_modules/jose": {
|
"node_modules/next-auth/node_modules/jose": {
|
||||||
"version": "4.15.4",
|
"version": "4.15.9",
|
||||||
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz",
|
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz",
|
||||||
"integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==",
|
"integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==",
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/panva"
|
"url": "https://github.com/sponsors/panva"
|
||||||
}
|
}
|
||||||
@ -11431,10 +11400,11 @@
|
|||||||
"integrity": "sha512-f7h4svPtl+QidoBv4taKXUjJ70G2asaZ8G28nS0OkqaalX8dwwrtWtyxEDPK62AC00ur/+/E0pUwBwY5EPn15Q=="
|
"integrity": "sha512-f7h4svPtl+QidoBv4taKXUjJ70G2asaZ8G28nS0OkqaalX8dwwrtWtyxEDPK62AC00ur/+/E0pUwBwY5EPn15Q=="
|
||||||
},
|
},
|
||||||
"node_modules/next/node_modules/@swc/helpers": {
|
"node_modules/next/node_modules/@swc/helpers": {
|
||||||
"version": "0.5.2",
|
"version": "0.5.5",
|
||||||
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz",
|
||||||
"integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==",
|
"integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@swc/counter": "^0.1.3",
|
||||||
"tslib": "^2.4.0"
|
"tslib": "^2.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -14583,9 +14553,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/openid-client/node_modules/jose": {
|
"node_modules/openid-client/node_modules/jose": {
|
||||||
"version": "4.15.4",
|
"version": "4.15.9",
|
||||||
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz",
|
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz",
|
||||||
"integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==",
|
"integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==",
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/panva"
|
"url": "https://github.com/sponsors/panva"
|
||||||
}
|
}
|
||||||
@ -15118,20 +15088,34 @@
|
|||||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz",
|
||||||
"integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew=="
|
"integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew=="
|
||||||
},
|
},
|
||||||
|
"node_modules/printj": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==",
|
||||||
|
"bin": {
|
||||||
|
"printj": "bin/printj.njs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/prisma": {
|
"node_modules/prisma": {
|
||||||
"version": "5.15.0",
|
"version": "5.19.1",
|
||||||
"resolved": "https://registry.npmjs.org/prisma/-/prisma-5.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/prisma/-/prisma-5.19.1.tgz",
|
||||||
"integrity": "sha512-JA81ACQSCi3a7NUOgonOIkdx8PAVkO+HbUOxmd00Yb8DgIIEpr2V9+Qe/j6MLxIgWtE/OtVQ54rVjfYRbZsCfw==",
|
"integrity": "sha512-c5K9MiDaa+VAAyh1OiYk76PXOme9s3E992D7kvvIOhCrNsBQfy2mP2QAQtX0WNj140IgG++12kwZpYB9iIydNQ==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@prisma/engines": "5.15.0"
|
"@prisma/engines": "5.19.1"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"prisma": "build/index.js"
|
"prisma": "build/index.js"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16.13"
|
"node": ">=16.13"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"fsevents": "2.3.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/prisma-json-schema-generator": {
|
"node_modules/prisma-json-schema-generator": {
|
||||||
@ -15248,11 +15232,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/qs": {
|
"node_modules/qs": {
|
||||||
"version": "6.11.2",
|
"version": "6.13.0",
|
||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz",
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
|
||||||
"integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==",
|
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"side-channel": "^1.0.4"
|
"side-channel": "^1.0.6"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.6"
|
"node": ">=0.6"
|
||||||
@ -15367,9 +15351,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/raw-body": {
|
"node_modules/raw-body": {
|
||||||
"version": "2.5.1",
|
"version": "2.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
|
||||||
"integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
|
"integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bytes": "3.1.2",
|
"bytes": "3.1.2",
|
||||||
"http-errors": "2.0.0",
|
"http-errors": "2.0.0",
|
||||||
@ -16318,9 +16302,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/send": {
|
"node_modules/send": {
|
||||||
"version": "0.18.0",
|
"version": "0.19.0",
|
||||||
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
|
||||||
"integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
|
"integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": "2.6.9",
|
"debug": "2.6.9",
|
||||||
"depd": "2.0.0",
|
"depd": "2.0.0",
|
||||||
@ -16340,6 +16324,14 @@
|
|||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/send/node_modules/encodeurl": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/send/node_modules/mime": {
|
"node_modules/send/node_modules/mime": {
|
||||||
"version": "1.6.0",
|
"version": "1.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||||
@ -16365,14 +16357,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/serve-static": {
|
"node_modules/serve-static": {
|
||||||
"version": "1.15.0",
|
"version": "1.16.2",
|
||||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
|
||||||
"integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
|
"integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"encodeurl": "~1.0.2",
|
"encodeurl": "~2.0.0",
|
||||||
"escape-html": "~1.0.3",
|
"escape-html": "~1.0.3",
|
||||||
"parseurl": "~1.3.3",
|
"parseurl": "~1.3.3",
|
||||||
"send": "0.18.0"
|
"send": "0.19.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
@ -18386,21 +18378,20 @@
|
|||||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||||
},
|
},
|
||||||
"node_modules/webpack": {
|
"node_modules/webpack": {
|
||||||
"version": "5.91.0",
|
"version": "5.94.0",
|
||||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz",
|
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz",
|
||||||
"integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==",
|
"integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/eslint-scope": "^3.7.3",
|
|
||||||
"@types/estree": "^1.0.5",
|
"@types/estree": "^1.0.5",
|
||||||
"@webassemblyjs/ast": "^1.12.1",
|
"@webassemblyjs/ast": "^1.12.1",
|
||||||
"@webassemblyjs/wasm-edit": "^1.12.1",
|
"@webassemblyjs/wasm-edit": "^1.12.1",
|
||||||
"@webassemblyjs/wasm-parser": "^1.12.1",
|
"@webassemblyjs/wasm-parser": "^1.12.1",
|
||||||
"acorn": "^8.7.1",
|
"acorn": "^8.7.1",
|
||||||
"acorn-import-assertions": "^1.9.0",
|
"acorn-import-attributes": "^1.9.5",
|
||||||
"browserslist": "^4.21.10",
|
"browserslist": "^4.21.10",
|
||||||
"chrome-trace-event": "^1.0.2",
|
"chrome-trace-event": "^1.0.2",
|
||||||
"enhanced-resolve": "^5.16.0",
|
"enhanced-resolve": "^5.17.1",
|
||||||
"es-module-lexer": "^1.2.1",
|
"es-module-lexer": "^1.2.1",
|
||||||
"eslint-scope": "5.1.1",
|
"eslint-scope": "5.1.1",
|
||||||
"events": "^3.2.0",
|
"events": "^3.2.0",
|
||||||
@ -18474,26 +18465,6 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/webpack-bundle-analyzer/node_modules/ws": {
|
|
||||||
"version": "7.5.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz",
|
|
||||||
"integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8.3.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"bufferutil": "^4.0.1",
|
|
||||||
"utf-8-validate": "^5.0.2"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"bufferutil": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"utf-8-validate": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/webpack-sources": {
|
"node_modules/webpack-sources": {
|
||||||
"version": "3.2.3",
|
"version": "3.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
|
||||||
@ -18644,6 +18615,22 @@
|
|||||||
"node": ">= 12.0.0"
|
"node": ">= 12.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/wmf": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/word": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz",
|
||||||
|
"integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/wordwrap": {
|
"node_modules/wordwrap": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
|
||||||
@ -19092,6 +19079,26 @@
|
|||||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/ws": {
|
||||||
|
"version": "7.5.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
|
||||||
|
"integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.3.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bufferutil": "^4.0.1",
|
||||||
|
"utf-8-validate": "^5.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"bufferutil": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"utf-8-validate": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/x-is-array": {
|
"node_modules/x-is-array": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/x-is-array/-/x-is-array-0.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/x-is-array/-/x-is-array-0.1.0.tgz",
|
||||||
@ -19114,6 +19121,88 @@
|
|||||||
"node": ">=0.8"
|
"node": ">=0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/xlsx-js-style": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/xlsx-js-style/-/xlsx-js-style-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-DDT4FXFSWfT4DXMSok/m3TvmP1gvO3dn0Eu/c+eXHW5Kzmp7IczNkxg/iEPnImbG9X0Vb8QhROda5eatSR/97Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"adler-32": "~1.2.0",
|
||||||
|
"cfb": "^1.1.4",
|
||||||
|
"codepage": "~1.14.0",
|
||||||
|
"commander": "~2.17.1",
|
||||||
|
"crc-32": "~1.2.0",
|
||||||
|
"exit-on-epipe": "~1.0.1",
|
||||||
|
"fflate": "^0.3.8",
|
||||||
|
"ssf": "~0.11.2",
|
||||||
|
"wmf": "~1.0.1",
|
||||||
|
"word": "~0.3.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"xlsx": "bin/xlsx.njs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/xlsx-js-style/node_modules/adler-32": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-/vUqU/UY4MVeFsg+SsK6c+/05RZXIHZMGJA+PX5JyWI0ZRcBpupnRuPLU/NXXoFwMYCPCoxIfElM2eS+DUXCqQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"exit-on-epipe": "~1.0.1",
|
||||||
|
"printj": "~1.1.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"adler32": "bin/adler32.njs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/xlsx-js-style/node_modules/codepage": {
|
||||||
|
"version": "1.14.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/codepage/-/codepage-1.14.0.tgz",
|
||||||
|
"integrity": "sha512-iz3zJLhlrg37/gYRWgEPkaFTtzmnEv1h+r7NgZum2lFElYQPi0/5bnmuDfODHxfp0INEfnRqyfyeIJDbb7ahRw==",
|
||||||
|
"dependencies": {
|
||||||
|
"commander": "~2.14.1",
|
||||||
|
"exit-on-epipe": "~1.0.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"codepage": "bin/codepage.njs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/xlsx-js-style/node_modules/codepage/node_modules/commander": {
|
||||||
|
"version": "2.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz",
|
||||||
|
"integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw=="
|
||||||
|
},
|
||||||
|
"node_modules/xlsx-js-style/node_modules/commander": {
|
||||||
|
"version": "2.17.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
|
||||||
|
"integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg=="
|
||||||
|
},
|
||||||
|
"node_modules/xlsx-js-style/node_modules/frac": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/xlsx-js-style/node_modules/ssf": {
|
||||||
|
"version": "0.11.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz",
|
||||||
|
"integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==",
|
||||||
|
"dependencies": {
|
||||||
|
"frac": "~1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/xlsx-style": {
|
"node_modules/xlsx-style": {
|
||||||
"version": "0.8.13",
|
"version": "0.8.13",
|
||||||
"resolved": "https://registry.npmjs.org/xlsx-style/-/xlsx-style-0.8.13.tgz",
|
"resolved": "https://registry.npmjs.org/xlsx-style/-/xlsx-style-0.8.13.tgz",
|
||||||
|
10
package.json
10
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "smws",
|
"name": "smws",
|
||||||
"version": "1.3.0",
|
"version": "1.3.5",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "SMWS | ССОМ | Специално Свидетелстване София",
|
"description": "SMWS | ССОМ | Специално Свидетелстване София",
|
||||||
"repository": "http://git.d-popov.com/popov/next-cart-app.git",
|
"repository": "http://git.d-popov.com/popov/next-cart-app.git",
|
||||||
@ -34,7 +34,7 @@
|
|||||||
"@mui/material": "^5.15.10",
|
"@mui/material": "^5.15.10",
|
||||||
"@mui/x-date-pickers": "^6.19.4",
|
"@mui/x-date-pickers": "^6.19.4",
|
||||||
"@premieroctet/next-crud": "^3.0.0",
|
"@premieroctet/next-crud": "^3.0.0",
|
||||||
"@prisma/client": "^5.15.0",
|
"@prisma/client": "^5.19.1",
|
||||||
"@react-pdf/renderer": "^3.3.8",
|
"@react-pdf/renderer": "^3.3.8",
|
||||||
"@tailwindcss/forms": "^0.5.7",
|
"@tailwindcss/forms": "^0.5.7",
|
||||||
"@types/multer": "^1.4.11",
|
"@types/multer": "^1.4.11",
|
||||||
@ -111,13 +111,13 @@
|
|||||||
"winston-daily-rotate-file": "^5.0.0",
|
"winston-daily-rotate-file": "^5.0.0",
|
||||||
"workbox-webpack-plugin": "^7.1.0",
|
"workbox-webpack-plugin": "^7.1.0",
|
||||||
"xlsx": "https://cdn.sheetjs.com/xlsx-0.19.1/xlsx-0.19.1.tgz",
|
"xlsx": "https://cdn.sheetjs.com/xlsx-0.19.1/xlsx-0.19.1.tgz",
|
||||||
"xlsx-style": "^0.8.13",
|
"xlsx-js-style": "^1.2.0",
|
||||||
"xml-js": "^1.6.11",
|
"xml-js": "^1.6.11",
|
||||||
"xml2js": "^0.6.2"
|
"xml2js": "^0.6.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"depcheck": "^1.4.7",
|
"depcheck": "^1.4.7",
|
||||||
"prisma": "^5.15.0"
|
"prisma": "^5.19.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,6 +77,10 @@ export const authOptions: NextAuthOptions = {
|
|||||||
{ id: "1", name: "admin", email: "admin@example.com", password: process.env.ADMIN_PASSWORD, role: "ADMIN", static: true }
|
{ id: "1", name: "admin", email: "admin@example.com", password: process.env.ADMIN_PASSWORD, role: "ADMIN", static: true }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if (process.env.ADMIN_PASSWORD !== credentials.password) {
|
||||||
|
throw new Error('невалидна парола');
|
||||||
|
}
|
||||||
|
|
||||||
const user = users.find(user =>
|
const user = users.find(user =>
|
||||||
user.name === credentials.username && user.password === credentials.password
|
user.name === credentials.username && user.password === credentials.password
|
||||||
);
|
);
|
||||||
|
@ -12,6 +12,7 @@ import fs from 'fs';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { all } from "axios";
|
import { all } from "axios";
|
||||||
import { logger } from "src/helpers/common";
|
import { logger } from "src/helpers/common";
|
||||||
|
import { excel } from "src/helpers/excel";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -432,7 +433,13 @@ export default async function handler(req, res) {
|
|||||||
case "getAllPublishersWithStatistics":
|
case "getAllPublishersWithStatistics":
|
||||||
let noEndDate = common.parseBool(req.query.noEndDate);
|
let noEndDate = common.parseBool(req.query.noEndDate);
|
||||||
res.status(200).json(await dataHelper.getAllPublishersWithStatisticsMonth(day, noEndDate));
|
res.status(200).json(await dataHelper.getAllPublishersWithStatisticsMonth(day, noEndDate));
|
||||||
|
case "exportPublishersExcel":
|
||||||
|
try {
|
||||||
|
await excel.ExportPublishersToExcel(req, res);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(JSON.stringify(error));
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
"message": "no action '" + action + "' found"
|
"message": "no action '" + action + "' found"
|
||||||
|
@ -94,6 +94,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||||||
where: {
|
where: {
|
||||||
isActive: true,
|
isActive: true,
|
||||||
isPublished: true,
|
isPublished: true,
|
||||||
|
// OR: [
|
||||||
|
// { isPublished: true },
|
||||||
|
// { user: { role: 'admin' } } // Todo: example. fix this
|
||||||
|
// ],
|
||||||
startTime: {
|
startTime: {
|
||||||
gte: fromDate,
|
gte: fromDate,
|
||||||
//lt: toDate,
|
//lt: toDate,
|
||||||
@ -152,15 +156,17 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||||||
//bold the text after - in the notes
|
//bold the text after - in the notes
|
||||||
notes: notes,
|
notes: notes,
|
||||||
notes_bold: notes_bold,
|
notes_bold: notes_bold,
|
||||||
names: shift.assignments
|
names: shift.assignments.length > 0
|
||||||
.map((assignment) => {
|
? shift.assignments
|
||||||
return (
|
.map((assignment) => {
|
||||||
assignment.publisher.firstName +
|
return (
|
||||||
" " +
|
assignment.publisher.firstName +
|
||||||
assignment.publisher.lastName
|
" " +
|
||||||
);
|
assignment.publisher.lastName
|
||||||
})
|
);
|
||||||
.join(", "),
|
})
|
||||||
|
.join(", ")
|
||||||
|
: shift.name,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (shiftSchedule.names.length > 0) {
|
if (shiftSchedule.names.length > 0) {
|
||||||
@ -246,6 +252,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
|
console.log(error);
|
||||||
res.status(500).json({ error: "Internal Server Error" });
|
res.status(500).json({ error: "Internal Server Error" });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -9,6 +9,7 @@ import Shift from '../../../components/calendar/ShiftComponent';
|
|||||||
import { DayOfWeek, UserRole } from '@prisma/client';
|
import { DayOfWeek, UserRole } from '@prisma/client';
|
||||||
import { env } from 'process'
|
import { env } from 'process'
|
||||||
import ShiftComponent from '../../../components/calendar/ShiftComponent';
|
import ShiftComponent from '../../../components/calendar/ShiftComponent';
|
||||||
|
import PublisherShiftsModal from '../../../components/publisher/PublisherShiftsModal';
|
||||||
//import { set } from 'date-fns';
|
//import { set } from 'date-fns';
|
||||||
const common = require('src/helpers/common');
|
const common = require('src/helpers/common');
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
@ -66,6 +67,7 @@ export default function CalendarPage({ initialEvents, initialShifts }) {
|
|||||||
const [shifts, setShifts] = React.useState([]);
|
const [shifts, setShifts] = React.useState([]);
|
||||||
const [error, setError] = React.useState(null);
|
const [error, setError] = React.useState(null);
|
||||||
const [availablePubs, setAvailablePubs] = React.useState([]);
|
const [availablePubs, setAvailablePubs] = React.useState([]);
|
||||||
|
const [selectedPublisher, setSelectedPublisher] = React.useState(null);
|
||||||
|
|
||||||
const [selectedShiftId, setSelectedShiftId] = useState(null);
|
const [selectedShiftId, setSelectedShiftId] = useState(null);
|
||||||
|
|
||||||
@ -214,8 +216,8 @@ export default function CalendarPage({ initialEvents, initialShifts }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSelectedPublisher = (publisher) => {
|
const handleSelectedPublisher = (publisher) => {
|
||||||
// Do something with the selected publisher
|
|
||||||
console.log("handle pub clicked:", publisher);
|
console.log("handle pub clicked:", publisher);
|
||||||
|
setSelectedPublisher(publisher);
|
||||||
}
|
}
|
||||||
const handlePublisherModalOpen = async (publisher) => {
|
const handlePublisherModalOpen = async (publisher) => {
|
||||||
// Do something with the selected publisher
|
// Do something with the selected publisher
|
||||||
@ -355,7 +357,7 @@ export default function CalendarPage({ initialEvents, initialShifts }) {
|
|||||||
}
|
}
|
||||||
return <div>{" "}</div>;
|
return <div>{" "}</div>;
|
||||||
};
|
};
|
||||||
|
//ToDo: DRY - move to common
|
||||||
const addAssignment = async (publisher, shiftId) => {
|
const addAssignment = async (publisher, shiftId) => {
|
||||||
try {
|
try {
|
||||||
console.log(`calendar.idx: new assignment for publisher ${publisher.id} - ${publisher.firstName} ${publisher.lastName}`);
|
console.log(`calendar.idx: new assignment for publisher ${publisher.id} - ${publisher.firstName} ${publisher.lastName}`);
|
||||||
@ -365,6 +367,10 @@ export default function CalendarPage({ initialEvents, initialShifts }) {
|
|||||||
isConfirmed: true
|
isConfirmed: true
|
||||||
};
|
};
|
||||||
const { data } = await axiosInstance.post("/api/data/assignments", newAssignment);
|
const { data } = await axiosInstance.post("/api/data/assignments", newAssignment);
|
||||||
|
if (selectedShiftId == shiftId) {
|
||||||
|
handleShiftSelection(shifts.find(shift => shift.id === shiftId));
|
||||||
|
}
|
||||||
|
|
||||||
// Update the 'publisher' property of the returned data with the full publisher object
|
// Update the 'publisher' property of the returned data with the full publisher object
|
||||||
data.publisher = publisher;
|
data.publisher = publisher;
|
||||||
data.shift = shifts.find(shift => shift.id === shiftId);
|
data.shift = shifts.find(shift => shift.id === shiftId);
|
||||||
@ -779,7 +785,7 @@ export default function CalendarPage({ initialEvents, initialShifts }) {
|
|||||||
<input type="checkbox" className="toggle-checkbox" id="filterIncludeOldAvailabilities" onChange={handleCheckboxChange} />
|
<input type="checkbox" className="toggle-checkbox" id="filterIncludeOldAvailabilities" onChange={handleCheckboxChange} />
|
||||||
<span className="toggle-slider m-1">със стари предпочитания</span>
|
<span className="toggle-slider m-1">със стари предпочитания</span>
|
||||||
</label>
|
</label>
|
||||||
<ul className="w-full max-w-md">
|
<ul className="w-full max-w-md" id="availablePubsList" name="availablePubsList">
|
||||||
{Array.isArray(availablePubs) && availablePubs?.map((pub, index) => {
|
{Array.isArray(availablePubs) && availablePubs?.map((pub, index) => {
|
||||||
// Determine background and border classes based on conditions
|
// Determine background and border classes based on conditions
|
||||||
let bgAndBorderColorClass;
|
let bgAndBorderColorClass;
|
||||||
@ -814,8 +820,8 @@ export default function CalendarPage({ initialEvents, initialShifts }) {
|
|||||||
<li key={index}
|
<li key={index}
|
||||||
className={`flex justify-between items-center p-4 sm:py-2 rounded-lg shadow-sm mb-2
|
className={`flex justify-between items-center p-4 sm:py-2 rounded-lg shadow-sm mb-2
|
||||||
${bgAndBorderColorClass} ${selectedBorderClass} ${activeOpacityClass}
|
${bgAndBorderColorClass} ${selectedBorderClass} ${activeOpacityClass}
|
||||||
${pub.currentMonthAssignments >= pub.desiredShiftsPerMonth ? 'text-gray-400' : 'text-gray-800'}`}
|
${pub.currentMonthAssignments === pub.desiredShiftsPerMonth ? 'text-gray-400' : pub.currentMonthAssignments > pub.desiredShiftsPerMonth ? 'text-orange-300' : 'text-gray-800'}`}
|
||||||
onDoubleClick={(handlePublisherModalOpen.bind(this, pub))}
|
onDoubleClick={() => handlePublisherModalOpen(pub)}
|
||||||
>
|
>
|
||||||
<span className={`${pub.isAvailableForShift ? 'font-bold' : 'font-medium'} `}>
|
<span className={`${pub.isAvailableForShift ? 'font-bold' : 'font-medium'} `}>
|
||||||
{pub.firstName} {pub.lastName}
|
{pub.firstName} {pub.lastName}
|
||||||
@ -831,36 +837,10 @@ export default function CalendarPage({ initialEvents, initialShifts }) {
|
|||||||
<button tooltip="желани участия на месец" title="желани участия" className={`badge py-1 px-2 rounded-md text-xs ${pub.desiredShiftsPerMonth ? 'bg-purple-500 text-white' : 'bg-purple-200 text-gray-400'}`}>{pub.desiredShiftsPerMonth || 0}</button>
|
<button tooltip="желани участия на месец" title="желани участия" className={`badge py-1 px-2 rounded-md text-xs ${pub.desiredShiftsPerMonth ? 'bg-purple-500 text-white' : 'bg-purple-200 text-gray-400'}`}>{pub.desiredShiftsPerMonth || 0}</button>
|
||||||
<button tooltip="push" title="push" className={`badge py-1 px-2 rounded-md text-xs bg-red-100`}
|
<button tooltip="push" title="push" className={`badge py-1 px-2 rounded-md text-xs bg-red-100`}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await fetch('/api/notify', {
|
handleSelectedPublisher(pub);
|
||||||
method: 'POST',
|
addAssignment(pub, selectedShiftId);
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
id: pub.id,
|
|
||||||
message: "Тестово съобщение",
|
|
||||||
title: "Това е тестово съобщение от https://sofia.mwitnessing.com",
|
|
||||||
actions: [
|
|
||||||
{ action: 'OK', title: 'OK', icon: '✅' },
|
|
||||||
{ action: 'close', title: 'Затвори', icon: '❌' }
|
|
||||||
]
|
|
||||||
// actions: [
|
|
||||||
// {
|
|
||||||
// title: 'Open URL',
|
|
||||||
// action: 'open_url',
|
|
||||||
// icon: '/images/open-url.png'
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: 'Dismiss',
|
|
||||||
// action: 'dismiss',
|
|
||||||
// icon: '/images/dismiss.png'
|
|
||||||
// }
|
|
||||||
// ]
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}}
|
}}
|
||||||
>+</button>
|
>+</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
@ -899,151 +879,22 @@ export default function CalendarPage({ initialEvents, initialShifts }) {
|
|||||||
<div>
|
<div>
|
||||||
{/* <CustomCalendar date={value} shifts={shifts} /> */}
|
{/* <CustomCalendar date={value} shifts={shifts} /> */}
|
||||||
</div>
|
</div>
|
||||||
{isModalOpen && <PublisherShiftsModal publisher={modalPub} shifts={allShifts} onClose={() => setIsModalOpen(false)} />}
|
{isModalOpen && (
|
||||||
|
<PublisherShiftsModal
|
||||||
|
publisher={modalPub}
|
||||||
|
_shifts={allShifts}
|
||||||
|
onClose={() => setIsModalOpen(false)}
|
||||||
|
date={value}
|
||||||
|
onAssignmentChange={handleAssignmentChange}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</ProtectedRoute >
|
</ProtectedRoute >
|
||||||
</Layout >
|
</Layout >
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
function PublisherShiftsModal({ publisher, shifts, onClose }) {
|
|
||||||
const monthInfo = common.getMonthDatesInfo(new Date(value));
|
|
||||||
const monthShifts = shifts.filter(shift => {
|
|
||||||
const shiftDate = new Date(shift.startTime);
|
|
||||||
return shiftDate > monthInfo.firstDay && shiftDate < monthInfo.lastDay;
|
|
||||||
});
|
|
||||||
const weekShifts = monthShifts.filter(shift => {
|
|
||||||
const shiftDate = new Date(shift.startTime);
|
|
||||||
return common.getStartOfWeek(value) <= shiftDate && shiftDate <= common.getEndOfWeek(value);
|
|
||||||
});
|
|
||||||
const dayShifts = weekShifts.map(shift => {
|
|
||||||
const isAvailable = publisher.availabilities?.some(avail =>
|
|
||||||
avail.startTime <= shift.startTime && avail.endTime >= shift.endTime
|
|
||||||
);
|
|
||||||
let color = isAvailable ? getColorForShift(shift) : 'bg-gray-300';
|
|
||||||
if (shift.isFromPreviousMonth) {
|
|
||||||
color += ' border-l-4 border-orange-500 ';
|
|
||||||
}
|
|
||||||
if (shift.isFromPreviousAssignment) {
|
|
||||||
color += ' border-l-4 border-red-500 ';
|
|
||||||
}
|
|
||||||
return { ...shift, isAvailable, color };
|
|
||||||
}).reduce((acc, shift) => {
|
|
||||||
const dayIndex = new Date(shift.startTime).getDay();
|
|
||||||
acc[dayIndex] = acc[dayIndex] || [];
|
|
||||||
acc[dayIndex].push(shift);
|
|
||||||
return acc;
|
|
||||||
}, {});
|
|
||||||
console.log("dayShifts:", dayShifts);
|
|
||||||
|
|
||||||
const hasAssignment = (shiftId) => {
|
|
||||||
// return publisher.assignments.some(ass => ass.shift.id == shiftId);
|
|
||||||
return publisher.assignments?.some(ass => {
|
|
||||||
//console.log(`Comparing: ${ass.shift.id} to ${shiftId}: ${ass.shift.id === shiftId}`);
|
|
||||||
return ass.shift.id === shiftId;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const handleKeyDown = (event) => {
|
|
||||||
if (event.key === 'Escape') {
|
|
||||||
console.log('ESC: closing modal.');
|
|
||||||
onClose(); // Call the onClose function when ESC key is pressed
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add event listener
|
|
||||||
window.addEventListener('keydown', handleKeyDown);
|
|
||||||
|
|
||||||
// Remove event listener on cleanup
|
|
||||||
return () => {
|
|
||||||
window.removeEventListener('keydown', handleKeyDown);
|
|
||||||
};
|
|
||||||
}, [onClose]); // Include onClose in the dependency array
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="fixed top-0 left-0 w-full h-full flex items-center justify-center bg-black bg-opacity-50 z-50">
|
|
||||||
<div className="relative bg-white p-8 rounded-lg shadow-xl max-w-xl w-full h-auto overflow-y-auto">
|
|
||||||
<h2 className="text-xl font-semibold mb-4">График на <span title={publisher.email} className='publisher'>
|
|
||||||
<strong>{publisher.firstName} {publisher.lastName}</strong>
|
|
||||||
<span className="publisher-tooltip" onClick={common.copyToClipboard}>{publisher.email}</span>
|
|
||||||
</span> тази седмица:</h2>
|
|
||||||
|
|
||||||
{/* ... Display shifts in a calendar-like UI ... */}
|
|
||||||
<div className="grid grid-cols-6 gap-4 mb-4">
|
|
||||||
{Object.entries(dayShifts).map(([dayIndex, shiftsForDay]) => (
|
|
||||||
<div key={dayIndex} className="flex flex-col space-y-2 justify-end">
|
|
||||||
{/* Day header */}
|
|
||||||
<div className="text-center font-medium">{new Date(shiftsForDay[0].startTime).getDate()}-ти</div>
|
|
||||||
|
|
||||||
{shiftsForDay.map((shift, index) => {
|
|
||||||
const assignmentExists = hasAssignment(shift.id);
|
|
||||||
const availability = publisher.availabilities.find(avail =>
|
|
||||||
avail.startTime <= shift.startTime && avail.endTime >= shift.endTime
|
|
||||||
);
|
|
||||||
const isFromPrevMonth = availability && availability.isFromPreviousMonth;
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
key={index}
|
|
||||||
className={`text-sm text-white p-2 rounded-md ${isFromPrevMonth ? 'border-l-6 border-black-500' : ''} ${shift.color} ${assignmentExists ? 'border-2 border-blue-500' : ""} h-24 flex flex-col justify-center`}
|
|
||||||
>
|
|
||||||
{common.getTimeRange(shift.startTime, shift.endTime)} {shift.id}
|
|
||||||
|
|
||||||
{!assignmentExists && shift.isAvailable && (
|
|
||||||
<button onClick={() => { addAssignment(publisher, shift.id); }}
|
|
||||||
className="mt-2 bg-green-500 text-white p-1 rounded hover:bg-green-600 active:bg-green-700 focus:outline-none"
|
|
||||||
>
|
|
||||||
добави
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
{assignmentExists && (
|
|
||||||
<button onClick={() => { removeAssignment(publisher, shift.id) }} // Implement the removeAssignment function
|
|
||||||
className="mt-2 bg-red-500 text-white p-1 rounded hover:bg-red-600 active:bg-red-700 focus:outline-none"
|
|
||||||
>
|
|
||||||
махни
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Close button in the top right corner */}
|
|
||||||
<button
|
|
||||||
onClick={onClose}
|
|
||||||
className="absolute top-3 right-2 p-2 px-3 bg-red-500 text-white rounded-full hover:bg-red-600 active:bg-red-700 focus:outline-none"
|
|
||||||
>
|
|
||||||
×
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{/* <Link href={`/cart/publishers/edit/${modalPub.id}`}
|
|
||||||
className="mt-2 bg-blue-500 text-white p-1 rounded hover:bg-blue-600 active:bg-blue-700 focus:outline-none">
|
|
||||||
<i className="fas fa-edit" />
|
|
||||||
</Link> */}
|
|
||||||
{/* Edit button in the top right corner, next to the close button */}
|
|
||||||
<Link href={`/cart/publishers/edit/${modalPub.id}`} className="absolute top-3 right-12 p-2 bg-blue-500 text-white rounded-full hover:bg-blue-600 active:bg-blue-700 focus:outline-none">
|
|
||||||
<i className="fas fa-edit" />
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div >
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getColorForShift(shift) {
|
|
||||||
const assignedCount = shift.assignedCount || 0; // Assuming each shift has an assignedCount property
|
|
||||||
switch (assignedCount) {
|
|
||||||
case 0: return 'bg-blue-300';
|
|
||||||
case 1: return 'bg-green-300';
|
|
||||||
case 2: return 'bg-yellow-300';
|
|
||||||
case 3: return 'bg-orange-300';
|
|
||||||
case 4: return 'bg-red-200';
|
|
||||||
default: return 'bg-gray-300';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
import axiosServer from '../../../src/axiosServer';
|
import axiosServer from '../../../src/axiosServer';
|
||||||
|
@ -15,8 +15,7 @@ import { levenshteinEditDistance } from "levenshtein-edit-distance";
|
|||||||
import ProtectedRoute from '../../../components/protectedRoute';
|
import ProtectedRoute from '../../../components/protectedRoute';
|
||||||
import ConfirmationModal from '../../../components/ConfirmationModal';
|
import ConfirmationModal from '../../../components/ConfirmationModal';
|
||||||
import { relative } from "path";
|
import { relative } from "path";
|
||||||
|
import { set } from "lodash";
|
||||||
|
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
initialItems: Publisher[];
|
initialItems: Publisher[];
|
||||||
@ -24,14 +23,31 @@ interface IProps {
|
|||||||
|
|
||||||
function PublishersPage({ publishers = [] }: IProps) {
|
function PublishersPage({ publishers = [] }: IProps) {
|
||||||
const [shownPubs, setShownPubs] = useState(publishers);
|
const [shownPubs, setShownPubs] = useState(publishers);
|
||||||
|
|
||||||
const [filter, setFilter] = useState("");
|
const [filter, setFilter] = useState("");
|
||||||
|
const [showZeroShiftsOnly, setShowZeroShiftsOnly] = useState(false);
|
||||||
const [filterIsImported, setFilterIsImported] = useState({
|
const [filterIsImported, setFilterIsImported] = useState({
|
||||||
checked: false,
|
checked: false,
|
||||||
indeterminate: true,
|
indeterminate: true,
|
||||||
});
|
});
|
||||||
const [showZeroShiftsOnly, setShowZeroShiftsOnly] = useState(false);
|
|
||||||
const [isDeleting, setIsDeleting] = useState(false);
|
|
||||||
|
|
||||||
|
// const cbRefFilterTraining = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
|
// const getCheckboxState = (currentState: boolean | null) => {
|
||||||
|
// if (currentState === true) return 'unchecked';
|
||||||
|
// if (currentState === false) return 'checked';
|
||||||
|
// return 'indeterminate';
|
||||||
|
// };
|
||||||
|
// const cbRefFilterTraining = useRef<HTMLInputElement>(null);
|
||||||
|
// const [cbFilterTrainingState, setcbFilterTrainingState] = useState<boolean | null>(null);
|
||||||
|
// useEffect(() => {
|
||||||
|
// if (cbRefFilterTraining.current) {
|
||||||
|
// cbRefFilterTraining.current.indeterminate = cbFilterTrainingState === null;
|
||||||
|
// }
|
||||||
|
// }, [cbFilterTrainingState]);
|
||||||
|
const [flterNoTraining, setFilterNoTraining] = useState(false);
|
||||||
|
|
||||||
|
const [isDeleting, setIsDeleting] = useState(false);
|
||||||
const [isModalOpenDeleteAllVisible, setIsModalOpenDeleteAllVisible] = useState(false);
|
const [isModalOpenDeleteAllVisible, setIsModalOpenDeleteAllVisible] = useState(false);
|
||||||
const [isModalOpenDeleteAllAvaillabilities, setIsModalOpenDeleteAllAvaillabilities] = useState(false);
|
const [isModalOpenDeleteAllAvaillabilities, setIsModalOpenDeleteAllAvaillabilities] = useState(false);
|
||||||
|
|
||||||
@ -102,10 +118,15 @@ function PublishersPage({ publishers = [] }: IProps) {
|
|||||||
? filteredPublishers.filter(p => p.assignments.length === 0)
|
? filteredPublishers.filter(p => p.assignments.length === 0)
|
||||||
: filteredPublishers;
|
: filteredPublishers;
|
||||||
|
|
||||||
setShownPubs(filteredPublishers);
|
// trained filter
|
||||||
}, [filter, showZeroShiftsOnly]);
|
if (flterNoTraining) {
|
||||||
|
filteredPublishers = filteredPublishers.filter(p => p.isTrained === false);
|
||||||
|
}
|
||||||
|
|
||||||
|
setShownPubs(filteredPublishers);
|
||||||
|
}, [filter, showZeroShiftsOnly, flterNoTraining]);
|
||||||
|
|
||||||
|
|
||||||
const checkboxRef = useRef();
|
|
||||||
|
|
||||||
const renderPublishers = () => {
|
const renderPublishers = () => {
|
||||||
if (shownPubs.length === 0) {
|
if (shownPubs.length === 0) {
|
||||||
@ -138,31 +159,33 @@ function PublishersPage({ publishers = [] }: IProps) {
|
|||||||
if (type === 'text') {
|
if (type === 'text') {
|
||||||
setFilter(value);
|
setFilter(value);
|
||||||
} else if (type === 'checkbox') {
|
} else if (type === 'checkbox') {
|
||||||
// setFilterIsImported({ ...checkboxFilter, [name]: checked });
|
if (name === 'filterIsImported') {
|
||||||
const { checked, indeterminate } = checkboxRef.current;
|
setFilterIsImported({ checked, indeterminate: false });
|
||||||
if (!checked && !indeterminate) {
|
}
|
||||||
// Checkbox was unchecked, set it to indeterminate state
|
if (name === 'filterTrained') {
|
||||||
checkboxRef.current.indeterminate = true;
|
// const nextState = cbFilterTrainingState === false ? null : cbFilterTrainingState === null ? true : false;
|
||||||
setFilterIsImported({ checked: false, indeterminate: true });
|
// setcbFilterTrainingState(nextState);
|
||||||
} else if (!checked && indeterminate) {
|
setFilterNoTraining(checked);
|
||||||
// Checkbox was indeterminate, set it to checked state
|
|
||||||
checkboxRef.current.checked = true;
|
|
||||||
checkboxRef.current.indeterminate = false;
|
|
||||||
setFilterIsImported({ checked: true, indeterminate: false });
|
|
||||||
} else if (checked && !indeterminate) {
|
|
||||||
// Checkbox was checked, set it to unchecked state
|
|
||||||
checkboxRef.current.checked = false;
|
|
||||||
checkboxRef.current.indeterminate = false;
|
|
||||||
setFilterIsImported({ checked: false, indeterminate: false });
|
|
||||||
} else {
|
|
||||||
// Checkbox was checked and indeterminate (should not happen), set it to unchecked state
|
|
||||||
checkboxRef.current.checked = false;
|
|
||||||
checkboxRef.current.indeterminate = false;
|
|
||||||
setFilterIsImported({ checked: false, indeterminate: false });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const exportPublishers = async () => {
|
||||||
|
try {
|
||||||
|
const response = await axiosInstance.get('/api/?action=exportPublishersExcel');
|
||||||
|
const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = 'publishers.xlsx';
|
||||||
|
a.click();
|
||||||
|
} catch (error) {
|
||||||
|
console.error(JSON.stringify(error)); // Log the error
|
||||||
|
toast.error("Грешка при експорт на данни");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<ProtectedRoute allowedRoles={[UserRole.ADMIN, UserRole.POWERUSER]}>
|
<ProtectedRoute allowedRoles={[UserRole.ADMIN, UserRole.POWERUSER]}>
|
||||||
@ -195,8 +218,13 @@ function PublishersPage({ publishers = [] }: IProps) {
|
|||||||
<div className="flex justify-center m-4">
|
<div className="flex justify-center m-4">
|
||||||
<a href="/cart/publishers/import" className="btn">Import publishers</a>
|
<a href="/cart/publishers/import" className="btn">Import publishers</a>
|
||||||
</div>
|
</div>
|
||||||
|
{/* export by calling excel helper .ExportPublishersToExcel() */}
|
||||||
|
<div className="flex justify-center m-4">
|
||||||
|
<button className="btn" onClick={exportPublishers}>Export to Excel</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div className="z-60 sticky top-0" style={{ zIndex: 60, position: relative }}>
|
<div className="z-60 sticky top-0" style={{ zIndex: 60, position: relative }}>
|
||||||
<div name="filters" className="flex items-center justify-center space-x-4 m-4 bg-gray-100 p-2" >
|
<div name="filters" className="flex items-center justify-center space-x-4 m-4 bg-gray-100 p-2" >
|
||||||
<label htmlFor="filter">Filter:</label>
|
<label htmlFor="filter">Filter:</label>
|
||||||
@ -212,7 +240,17 @@ function PublishersPage({ publishers = [] }: IProps) {
|
|||||||
<span className="ml-2">само без смени</span>
|
<span className="ml-2">само без смени</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<span id="filter-info" className="ml-4">{publishers.length} от {publishers.length} вестителя</span>
|
<label htmlFor="filterTrained" className="ml-4 inline-flex items-center">
|
||||||
|
<input type="checkbox" id="filterTrained" name="filterTrained"
|
||||||
|
// support intermediate state if checkboxState is null
|
||||||
|
checked={flterNoTraining}
|
||||||
|
onChange={handleFilterChange}
|
||||||
|
className="form-checkbox text-indigo-600"
|
||||||
|
/>
|
||||||
|
<span className="ml-2">без обучение</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<span id="filter-info" className="ml-4">{shownPubs.length} от {publishers.length} вестителя</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-4 grid-cols-1 md:grid-cols-4 z-0">
|
<div className="grid gap-4 grid-cols-1 md:grid-cols-4 z-0">
|
||||||
@ -226,12 +264,12 @@ function PublishersPage({ publishers = [] }: IProps) {
|
|||||||
|
|
||||||
export default PublishersPage;
|
export default PublishersPage;
|
||||||
|
|
||||||
//import { set } from "date-fns";
|
//import {set} from "date-fns";
|
||||||
|
|
||||||
export const getServerSideProps = async (context) => {
|
export const getServerSideProps = async (context) => {
|
||||||
// const axios = await axiosServer(context);
|
// const axios = await axiosServer(context);
|
||||||
// //ToDo: refactor all axios calls to use axiosInstance and this URL
|
// //ToDo: refactor all axios calls to use axiosInstance and this URL
|
||||||
// const { data: publishers } = await axios.get('/api/data/publishers?select=id,firstName,lastName,email,isActive,isTrained,isImported,assignments.shift.startTime,availabilities.startTime&dev=fromuseefect');
|
// const {data: publishers } = await axios.get('/api/data/publishers?select=id,firstName,lastName,email,isActive,isTrained,isImported,assignments.shift.startTime,availabilities.startTime&dev=fromuseefect');
|
||||||
//use prisma instead of axios
|
//use prisma instead of axios
|
||||||
const prisma = common.getPrismaClient();
|
const prisma = common.getPrismaClient();
|
||||||
let publishers = await prisma.publisher.findMany({
|
let publishers = await prisma.publisher.findMany({
|
||||||
|
@ -9,7 +9,7 @@ import ProtectedRoute from '../../../components/protectedRoute';
|
|||||||
function NewPage(loc: Location) {
|
function NewPage(loc: Location) {
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<ProtectedRoute allowedRoles={[UserRole.POWERUSER, UserRole.ADMIN]}>
|
<ProtectedRoute allowedRoles={[UserRole.USER, UserRole.POWERUSER, UserRole.ADMIN]}>
|
||||||
<div className="h-5/6 grid place-items-center">
|
<div className="h-5/6 grid place-items-center">
|
||||||
<ExperienceForm />
|
<ExperienceForm />
|
||||||
</div></ProtectedRoute>
|
</div></ProtectedRoute>
|
||||||
|
@ -105,7 +105,12 @@ export default PDFViewerPage;
|
|||||||
|
|
||||||
|
|
||||||
export const getServerSideProps = async (context) => {
|
export const getServerSideProps = async (context) => {
|
||||||
const permitsFolder = '/public/content/permits/';
|
const permitsFolder = path.join('public', 'content', 'permits');
|
||||||
|
|
||||||
|
// Create folders if they do not exist
|
||||||
|
if (!fs.existsSync(permitsFolder)) {
|
||||||
|
fs.mkdirSync(permitsFolder, { recursive: true });
|
||||||
|
}
|
||||||
//get all the files in the permits folder order them by date desc and display them
|
//get all the files in the permits folder order them by date desc and display them
|
||||||
const pdfFiles = fs.readdirSync(path.join(process.cwd(), permitsFolder)).map(file => {
|
const pdfFiles = fs.readdirSync(path.join(process.cwd(), permitsFolder)).map(file => {
|
||||||
return {
|
return {
|
||||||
|
5
prisma/migrations/20240621124135_/migration.sql
Normal file
5
prisma/migrations/20240621124135_/migration.sql
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE `Message` MODIFY `content` TEXT NOT NULL;
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE `Survey` MODIFY `content` TEXT NOT NULL;
|
@ -0,0 +1,6 @@
|
|||||||
|
-- DropForeignKey
|
||||||
|
ALTER TABLE `Message` DROP FOREIGN KEY `Message_publisherId_fkey`;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE `Message`
|
||||||
|
ADD CONSTRAINT `Message_publisherId_fkey` FOREIGN KEY (`publisherId`) REFERENCES `Publisher` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
@ -266,7 +266,7 @@ enum MessageType {
|
|||||||
|
|
||||||
model Survey {
|
model Survey {
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
content String
|
content String @db.Text
|
||||||
answers Json?
|
answers Json?
|
||||||
messages Message[]
|
messages Message[]
|
||||||
publicFrom DateTime?
|
publicFrom DateTime?
|
||||||
@ -275,10 +275,10 @@ model Survey {
|
|||||||
|
|
||||||
model Message {
|
model Message {
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
publisher Publisher @relation(fields: [publisherId], references: [id])
|
publisher Publisher @relation(fields: [publisherId], references: [id], onDelete: Cascade)
|
||||||
publisherId String
|
publisherId String
|
||||||
date DateTime
|
date DateTime
|
||||||
content String
|
content String @db.Text
|
||||||
isRead Boolean @default(false)
|
isRead Boolean @default(false)
|
||||||
isPublic Boolean @default(false)
|
isPublic Boolean @default(false)
|
||||||
type MessageType @default(Email)
|
type MessageType @default(Email)
|
||||||
@ -305,7 +305,7 @@ model EventLog {
|
|||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
date DateTime
|
date DateTime
|
||||||
publisherId String?
|
publisherId String?
|
||||||
publisher Publisher? @relation(fields: [publisherId], references: [id])
|
publisher Publisher? @relation(fields: [publisherId], references: [id], onDelete: SetNull)
|
||||||
shiftId Int?
|
shiftId Int?
|
||||||
shift Shift? @relation(fields: [shiftId], references: [id])
|
shift Shift? @relation(fields: [shiftId], references: [id])
|
||||||
content String @db.VarChar(5000)
|
content String @db.VarChar(5000)
|
||||||
|
Binary file not shown.
@ -574,7 +574,7 @@ nextApp
|
|||||||
|
|
||||||
// --------------- EXCEL EXPORT ROUTE ----------------
|
// --------------- EXCEL EXPORT ROUTE ----------------
|
||||||
server.get("/generatexcel/:year/:month/:process", async (req, res) => {
|
server.get("/generatexcel/:year/:month/:process", async (req, res) => {
|
||||||
await excel.GenerateExcel(req, res);
|
await excel.ScheduleGenerateExcel(req, res);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,8 +14,12 @@ const data = require("./data");
|
|||||||
|
|
||||||
// for nodejs
|
// for nodejs
|
||||||
//const api = require("./pages/api/index");
|
//const api = require("./pages/api/index");
|
||||||
|
// import dynamic from 'next/dynamic';
|
||||||
|
|
||||||
exports.GenerateExcel = async function (req, res) {
|
// const XLSX = dynamic(() => import('xlsx-style'), { ssr: false });
|
||||||
|
|
||||||
|
|
||||||
|
exports.ScheduleGenerateExcel = async function (req, res) {
|
||||||
|
|
||||||
const prisma = common.getPrismaClient();
|
const prisma = common.getPrismaClient();
|
||||||
const year = req.params.year;
|
const year = req.params.year;
|
||||||
@ -162,7 +166,7 @@ exports.GenerateExcel = async function (req, res) {
|
|||||||
const ws = XLSX.utils.aoa_to_sheet(ws_data);
|
const ws = XLSX.utils.aoa_to_sheet(ws_data);
|
||||||
wb.Sheets["График КОЛИЧКИ"] = ws;
|
wb.Sheets["График КОЛИЧКИ"] = ws;
|
||||||
|
|
||||||
const xlsxstyle = require("xlsx-style");
|
const xlsxstyle = require("xlsx-js-style");
|
||||||
try {
|
try {
|
||||||
const workbook = xlsxstyle.readFile(filePath);
|
const workbook = xlsxstyle.readFile(filePath);
|
||||||
const sheetNames = workbook.SheetNames;
|
const sheetNames = workbook.SheetNames;
|
||||||
@ -611,6 +615,55 @@ exports.ReadDocxFileForMonth = async function (filePath, buffer, month, year, pr
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
exports.ExportPublishersToExcel = async function (req, res) {
|
||||||
|
const prisma = common.getPrismaClient();
|
||||||
|
const publishers = await prisma.publisher.findMany({
|
||||||
|
// where: { isActive: true, },
|
||||||
|
include: {
|
||||||
|
// availabilities: { where: { isActive: true, }, },
|
||||||
|
// assignments: { include: { shift: true, }, },
|
||||||
|
congregation: true,
|
||||||
|
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const ExcelJS = require("exceljs");
|
||||||
|
const xjswb = new ExcelJS.Workbook();
|
||||||
|
const sheet = xjswb.addWorksheet("Publishers");
|
||||||
|
sheet.columns = [
|
||||||
|
{ header: "Name", key: "name", width: 32 },
|
||||||
|
{ header: "Trained", key: "trained", width: 10 },
|
||||||
|
{ header: "Email", key: "email", width: 32 },
|
||||||
|
{ header: "Phone", key: "phone", width: 32 },
|
||||||
|
{ header: "Role", key: "role", width: 32 },
|
||||||
|
{ header: "Congregation", key: "congregationName", width: 32 },
|
||||||
|
{ header: "Last Login", key: "lastLogin", width: 32 },
|
||||||
|
{ header: "Type", key: "PublisherTypeText", width: 32 },
|
||||||
|
{ header: "Active", key: "isActive", width: 10 },
|
||||||
|
{ header: "Created At", key: "createdAt", width: 32 },
|
||||||
|
{ header: "Updated At", key: "updatedAt", width: 32 },
|
||||||
|
];
|
||||||
|
publishers.forEach((publisher) => {
|
||||||
|
sheet.addRow({
|
||||||
|
name: publisher.firstName + " " + publisher.lastName,
|
||||||
|
trained: publisher.isTrained,
|
||||||
|
email: publisher.email,
|
||||||
|
phone: publisher.phone,
|
||||||
|
role: publisher.role,
|
||||||
|
congregationName: publisher.congregation.name,
|
||||||
|
lastLogin: publisher.lastLogin,
|
||||||
|
PublisherTypeText: publisher.PublisherTypeText,
|
||||||
|
isActive: publisher.isActive,
|
||||||
|
createdAt: publisher.createdAt,
|
||||||
|
updatedAt: publisher.updatedAt,
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
res.setHeader("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
res.setHeader("Content-Disposition", "attachment; filename=" + encodeURI("Publishers.xlsx"));
|
||||||
|
xjswb.xlsx.write(res);
|
||||||
|
}
|
||||||
|
|
||||||
const weekNames = [
|
const weekNames = [
|
||||||
"Понеделник",
|
"Понеделник",
|
||||||
"Вторник",
|
"Вторник",
|
||||||
|
Reference in New Issue
Block a user