From af91c788f37d67fc6cee52b7812d9b5f0c54d658 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Thu, 10 Apr 2025 11:48:10 +0000 Subject: [PATCH] Revert to version f1c47de --- app-shell/src/_dev_schema.json | 3 - backend/src/db/api/likes.js | 246 --------- backend/src/db/migrations/1744285350750.js | 72 --- backend/src/db/migrations/1744285385406.js | 47 -- backend/src/db/models/likes.js | 49 -- .../db/seeders/20200430130760-user-roles.js | 26 - .../db/seeders/20231127130745-sample-data.js | 196 +------ backend/src/db/seeders/20250410114230.js | 87 ---- backend/src/index.js | 12 +- backend/src/routes/likes.js | 433 ---------------- backend/src/services/likes.js | 114 ----- backend/src/services/search.js | 2 - frontend/json/runtimeError.json | 1 - frontend/src/components/Likes/CardLikes.tsx | 109 ---- frontend/src/components/Likes/ListLikes.tsx | 90 ---- frontend/src/components/Likes/TableLikes.tsx | 481 ------------------ .../components/Likes/configureLikesCols.tsx | 73 --- frontend/src/menuAside.ts | 8 - frontend/src/pages/dashboard.tsx | 35 -- frontend/src/pages/likes/[likesId].tsx | 124 ----- frontend/src/pages/likes/likes-edit.tsx | 122 ----- frontend/src/pages/likes/likes-list.tsx | 160 ------ frontend/src/pages/likes/likes-new.tsx | 98 ---- frontend/src/pages/likes/likes-table.tsx | 159 ------ frontend/src/pages/likes/likes-view.tsx | 81 --- frontend/src/pages/web_pages/about.tsx | 14 +- frontend/src/pages/web_pages/home.tsx | 18 +- frontend/src/pages/web_pages/services.tsx | 14 +- frontend/src/stores/likes/likesSlice.ts | 236 --------- frontend/src/stores/store.ts | 2 - 30 files changed, 26 insertions(+), 3086 deletions(-) delete mode 100644 app-shell/src/_dev_schema.json delete mode 100644 backend/src/db/api/likes.js delete mode 100644 backend/src/db/migrations/1744285350750.js delete mode 100644 backend/src/db/migrations/1744285385406.js delete mode 100644 backend/src/db/models/likes.js delete mode 100644 backend/src/db/seeders/20250410114230.js delete mode 100644 backend/src/routes/likes.js delete mode 100644 backend/src/services/likes.js delete mode 100644 frontend/json/runtimeError.json delete mode 100644 frontend/src/components/Likes/CardLikes.tsx delete mode 100644 frontend/src/components/Likes/ListLikes.tsx delete mode 100644 frontend/src/components/Likes/TableLikes.tsx delete mode 100644 frontend/src/components/Likes/configureLikesCols.tsx delete mode 100644 frontend/src/pages/likes/[likesId].tsx delete mode 100644 frontend/src/pages/likes/likes-edit.tsx delete mode 100644 frontend/src/pages/likes/likes-list.tsx delete mode 100644 frontend/src/pages/likes/likes-new.tsx delete mode 100644 frontend/src/pages/likes/likes-table.tsx delete mode 100644 frontend/src/pages/likes/likes-view.tsx delete mode 100644 frontend/src/stores/likes/likesSlice.ts diff --git a/app-shell/src/_dev_schema.json b/app-shell/src/_dev_schema.json deleted file mode 100644 index b90fabb..0000000 --- a/app-shell/src/_dev_schema.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "f1c47deb22ad08fc840de2c8b62f22f652a9e406": "{\"project\":{\"login_page_config\":{\"illustration_type\":\"image\",\"illustration_position\":\"left\",\"illustration_image_description\":\"abstract education concept art\"},\"sample_data\":{\"courses\":[{\"title\":\"Introduction to Programming\",\"description\":\"Learn the basics of programming with Python.\"},{\"title\":\"Advanced Mathematics\",\"description\":\"Explore complex mathematical concepts and theories.\"},{\"title\":\"Digital Marketing\",\"description\":\"Master the art of online marketing strategies.\"},{\"title\":\"Graphic Design\",\"description\":\"Develop skills in design software and visual communication.\"},{\"title\":\"Business Management\",\"description\":\"Understand the fundamentals of managing a business.\"}],\"students\":[{\"name\":\"Alice Johnson\",\"email\":\"alice.johnson@example.com\"},{\"name\":\"Bob Smith\",\"email\":\"bob.smith@example.com\"},{\"name\":\"Charlie Brown\",\"email\":\"charlie.brown@example.com\"},{\"name\":\"Diana Prince\",\"email\":\"diana.prince@example.com\"},{\"name\":\"Ethan Hunt\",\"email\":\"ethan.hunt@example.com\"}],\"instructors\":[{\"name\":\"Dr. Emily Clark\",\"email\":\"emily.clark@example.com\",\"qualifications\":\"PhD in Computer Science\"},{\"name\":\"Prof. John Doe\",\"email\":\"john.doe@example.com\",\"qualifications\":\"MBA in Business Administration\"},{\"name\":\"Ms. Sarah Lee\",\"email\":\"sarah.lee@example.com\",\"qualifications\":\"MFA in Graphic Design\"},{\"name\":\"Mr. Michael Green\",\"email\":\"michael.green@example.com\",\"qualifications\":\"MSc in Mathematics\"},{\"name\":\"Dr. Olivia White\",\"email\":\"olivia.white@example.com\",\"qualifications\":\"PhD in Marketing\"}],\"enrollments\":[{\"student\":\"Alice Johnson\",\"course\":\"Introduction to Programming\",\"payment_status\":\"paid\"},{\"student\":\"Bob Smith\",\"course\":\"Advanced Mathematics\",\"payment_status\":\"pending\"},{\"student\":\"Charlie Brown\",\"course\":\"Digital Marketing\",\"payment_status\":\"overdue\"},{\"student\":\"Diana Prince\",\"course\":\"Graphic Design\",\"payment_status\":\"paid\"},{\"student\":\"Ethan Hunt\",\"course\":\"Business Management\",\"payment_status\":\"pending\"}],\"discussion_boards\":[{\"topic\":\"Python Basics\",\"course\":\"Introduction to Programming\"},{\"topic\":\"Calculus Challenges\",\"course\":\"Advanced Mathematics\"},{\"topic\":\"SEO Techniques\",\"course\":\"Digital Marketing\"},{\"topic\":\"Design Trends\",\"course\":\"Graphic Design\"},{\"topic\":\"Leadership Skills\",\"course\":\"Business Management\"}],\"analytics\":[{\"courses\":\"Introduction to Programming\",\"students\":\"Alice Johnson\",\"instructors\":\"Dr. Emily Clark\"},{\"courses\":\"Advanced Mathematics\",\"students\":\"Bob Smith\",\"instructors\":\"Mr. Michael Green\"},{\"courses\":\"Digital Marketing\",\"students\":\"Charlie Brown\",\"instructors\":\"Dr. Olivia White\"},{\"courses\":\"Graphic Design\",\"students\":\"Diana Prince\",\"instructors\":\"Ms. Sarah Lee\"},{\"courses\":\"Business Management\",\"students\":\"Ethan Hunt\",\"instructors\":\"Prof. John Doe\"}],\"roles_names\":[\"Education Director\",\"Course Manager\",\"Instructor\",\"Student Support\",\"Learner\"],\"roles_permissions\":[{\"Education Director\":{\"courses\":\"1111\",\"students\":\"1111\",\"instructors\":\"1111\",\"enrollments\":\"1111\",\"discussion_boards\":\"1111\",\"analytics\":\"1111\"}},{\"Course Manager\":{\"courses\":\"1111\",\"students\":\"1100\",\"instructors\":\"1100\",\"enrollments\":\"1111\",\"discussion_boards\":\"1100\",\"analytics\":\"1100\"}},{\"Instructor\":{\"courses\":\"1100\",\"students\":\"1100\",\"instructors\":\"1100\",\"enrollments\":\"1100\",\"discussion_boards\":\"1111\",\"analytics\":\"1100\"}},{\"Student Support\":{\"courses\":\"1100\",\"students\":\"1111\",\"instructors\":\"1100\",\"enrollments\":\"1111\",\"discussion_boards\":\"1100\",\"analytics\":\"1100\"}},{\"Learner\":{\"courses\":\"0100\",\"students\":\"0100\",\"instructors\":\"0100\",\"enrollments\":\"0100\",\"discussion_boards\":\"1111\",\"analytics\":\"0100\"}}]},\"theme\":\"whiteTheme\",\"multitenancy\":false,\"organization_entity\":\"\",\"with_website\":true,\"frontend\":\"react\",\"backend\":\"nodejs\",\"design\":\"tailwind\",\"db\":\"postgresql\",\"title\":\"save_schema_test\",\"advanced_roles_permissions\":true,\"project_uuid\":\"c015ebf1-da8b-4884-80de-63a043cc2150\"},\"entities\":[{\"name\":\"users\",\"show_field\":\"firstName\",\"fields\":[{\"type\":\"string\",\"name\":\"firstName\",\"title\":\"First Name\",\"show_in_form\":true,\"show_in_table\":true,\"editable\":false,\"unique\":false,\"multiline\":false},{\"type\":\"string\",\"name\":\"lastName\",\"title\":\"Last Name\",\"show_in_form\":true,\"show_in_table\":true,\"editable\":false,\"unique\":false,\"multiline\":false},{\"type\":\"string\",\"name\":\"phoneNumber\",\"title\":\"Phone Number\",\"show_in_form\":true,\"show_in_table\":true,\"editable\":false,\"unique\":false,\"multiline\":false},{\"type\":\"string\",\"name\":\"email\",\"title\":\"E-Mail\",\"show_in_form\":true,\"show_in_table\":true,\"editable\":false,\"unique\":true,\"multiline\":false},{\"type\":\"boolean\",\"name\":\"disabled\",\"title\":\"Disabled\",\"show_in_form\":true,\"show_in_table\":true,\"editable\":false,\"unique\":false},{\"type\":\"images\",\"name\":\"avatar\",\"title\":\"Avatar\",\"show_in_form\":true,\"show_in_table\":true,\"editable\":false,\"unique\":false},{\"type\":\"string\",\"name\":\"password\",\"title\":\"Password\",\"show_in_form\":false,\"show_in_table\":false,\"editable\":false,\"unique\":false,\"multiline\":false},{\"show_in_form\":false,\"show_in_table\":false,\"editable\":false,\"unique\":false,\"type\":\"boolean\",\"name\":\"emailVerified\",\"title\":\"Email Verified\"},{\"type\":\"string\",\"name\":\"emailVerificationToken\",\"title\":\"Email Verification Token\",\"show_in_form\":false,\"show_in_table\":false,\"editable\":false,\"unique\":false,\"multiline\":false},{\"type\":\"datetime\",\"name\":\"emailVerificationTokenExpiresAt\",\"title\":\"Email Verification Token Expires At\",\"show_in_form\":false,\"show_in_table\":false,\"editable\":false,\"unique\":false},{\"type\":\"string\",\"name\":\"passwordResetToken\",\"title\":\"Password Reset Token\",\"show_in_form\":false,\"show_in_table\":false,\"editable\":false,\"unique\":false,\"multiline\":false},{\"type\":\"datetime\",\"name\":\"passwordResetTokenExpiresAt\",\"title\":\"Password Reset Token Expires At\",\"show_in_form\":false,\"show_in_table\":false,\"editable\":false,\"unique\":false},{\"type\":\"string\",\"name\":\"provider\",\"title\":\"Provider\",\"show_in_form\":false,\"show_in_table\":false,\"editable\":false,\"unique\":false,\"multiline\":false},{\"name\":\"app_role\",\"type\":\"relation_one\",\"show_in_form\":true,\"show_in_table\":true,\"editable\":false,\"title\":\"App Role\",\"unique\":false,\"ref\":\"roles\"},{\"name\":\"custom_permissions\",\"type\":\"relation_many\",\"show_in_form\":true,\"show_in_table\":true,\"editable\":false,\"title\":\"Custom Permissions\",\"unique\":false,\"ref\":\"permissions\"}]},{\"name\":\"analytics\",\"show_field\":\"courses\",\"display_type\":{\"name\":\"card\"},\"icon\":\"mdiChartLine\",\"fields\":[{\"type\":\"relation_many\",\"name\":\"courses\",\"title\":\"Courses\",\"ref\":\"courses\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false},{\"type\":\"relation_many\",\"name\":\"students\",\"title\":\"Students\",\"ref\":\"students\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false},{\"type\":\"relation_many\",\"name\":\"instructors\",\"title\":\"Instructors\",\"ref\":\"instructors\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}]},{\"name\":\"courses\",\"show_field\":\"title\",\"display_type\":{\"name\":\"table\"},\"icon\":\"mdiBookOpenPageVariant\",\"fields\":[{\"type\":\"string\",\"name\":\"title\",\"title\":\"Title\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false},{\"type\":\"string\",\"name\":\"description\",\"title\":\"Description\",\"multiline\":true,\"wysiwygEditor\":true,\"show_in_form\":true,\"show_in_table\":true,\"unique\":false},{\"type\":\"relation_many\",\"name\":\"instructors\",\"title\":\"Instructors\",\"ref\":\"users\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false},{\"type\":\"relation_many\",\"name\":\"students\",\"title\":\"Students\",\"ref\":\"users\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false},{\"type\":\"relation_many\",\"name\":\"discussion_boards\",\"title\":\"DiscussionBoards\",\"ref\":\"discussion_boards\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}]},{\"name\":\"discussion_boards\",\"show_field\":\"topic\",\"display_type\":{\"name\":\"list\"},\"icon\":\"mdiForumOutline\",\"fields\":[{\"type\":\"string\",\"name\":\"topic\",\"title\":\"Topic\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false},{\"type\":\"relation_one\",\"name\":\"course\",\"title\":\"Course\",\"ref\":\"courses\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}]},{\"name\":\"enrollments\",\"show_field\":\"payment_status\",\"display_type\":{\"name\":\"table\"},\"icon\":\"mdiClipboardCheckOutline\",\"fields\":[{\"type\":\"relation_one\",\"name\":\"student\",\"title\":\"Student\",\"ref\":\"students\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false},{\"type\":\"relation_one\",\"name\":\"course\",\"title\":\"Course\",\"ref\":\"courses\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false},{\"type\":\"enum\",\"name\":\"payment_status\",\"title\":\"PaymentStatus\",\"options\":[\"paid\",\"pending\",\"overdue\"],\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}]},{\"name\":\"instructors\",\"show_field\":\"name\",\"display_type\":{\"name\":\"list\"},\"icon\":\"mdiAccountTie\",\"fields\":[{\"type\":\"string\",\"name\":\"name\",\"title\":\"Name\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false},{\"type\":\"string\",\"name\":\"email\",\"title\":\"Email\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false},{\"type\":\"string\",\"name\":\"qualifications\",\"title\":\"Qualifications\",\"multiline\":true,\"show_in_form\":true,\"show_in_table\":true,\"unique\":false},{\"type\":\"relation_many\",\"name\":\"courses\",\"title\":\"Courses\",\"ref\":\"courses\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}]},{\"name\":\"students\",\"show_field\":\"name\",\"display_type\":{\"name\":\"list\"},\"icon\":\"mdiSchool\",\"fields\":[{\"type\":\"string\",\"name\":\"name\",\"title\":\"Name\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false},{\"type\":\"string\",\"name\":\"email\",\"title\":\"Email\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false},{\"type\":\"relation_many\",\"name\":\"enrollments\",\"title\":\"Enrollments\",\"ref\":\"enrollments\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}]},{\"name\":\"roles\",\"publicEntity\":false,\"show_field\":\"name\",\"editable\":false,\"fields\":[{\"name\":\"name\",\"type\":\"string\",\"multiline\":false,\"wysiwygEditor\":false,\"show_in_form\":true,\"show_in_table\":true,\"editable\":false,\"title\":\"Name\",\"unique\":false},{\"name\":\"role_customization\",\"type\":\"string\",\"multiline\":false,\"wysiwygEditor\":false,\"show_in_form\":false,\"show_in_table\":false,\"editable\":false,\"title\":\"Role Customization\",\"unique\":false},{\"name\":\"permissions\",\"type\":\"relation_many\",\"show_in_form\":true,\"show_in_table\":true,\"editable\":false,\"title\":\"Permissions\",\"unique\":false,\"ref\":\"permissions\"}]},{\"name\":\"permissions\",\"publicEntity\":false,\"show_field\":\"name\",\"editable\":false,\"fields\":[{\"name\":\"name\",\"type\":\"string\",\"multiline\":false,\"wysiwygEditor\":false,\"show_in_form\":true,\"show_in_table\":true,\"editable\":false,\"title\":\"Name\",\"unique\":false}]}],\"migrations\":[{\"time\":1744283645026,\"changes\":[{\"type\":\"table:create\",\"payload\":{\"table\":\"users\"}},{\"type\":\"table:create\",\"payload\":{\"table\":\"analytics\"}},{\"type\":\"table:create\",\"payload\":{\"table\":\"courses\"}},{\"type\":\"table:create\",\"payload\":{\"table\":\"discussion_boards\"}},{\"type\":\"table:create\",\"payload\":{\"table\":\"enrollments\"}},{\"type\":\"table:create\",\"payload\":{\"table\":\"instructors\"}},{\"type\":\"table:create\",\"payload\":{\"table\":\"students\"}},{\"type\":\"table:create\",\"payload\":{\"table\":\"roles\"}},{\"type\":\"table:create\",\"payload\":{\"table\":\"permissions\"}},{\"type\":\"field:create\",\"payload\":{\"table\":\"users\",\"field\":{\"type\":\"string\",\"name\":\"firstName\",\"title\":\"First Name\",\"show_in_form\":true,\"show_in_table\":true,\"editable\":false,\"unique\":false,\"multiline\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"users\",\"field\":{\"type\":\"string\",\"name\":\"lastName\",\"title\":\"Last Name\",\"show_in_form\":true,\"show_in_table\":true,\"editable\":false,\"unique\":false,\"multiline\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"users\",\"field\":{\"type\":\"string\",\"name\":\"phoneNumber\",\"title\":\"Phone Number\",\"show_in_form\":true,\"show_in_table\":true,\"editable\":false,\"unique\":false,\"multiline\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"users\",\"field\":{\"type\":\"string\",\"name\":\"email\",\"title\":\"E-Mail\",\"show_in_form\":true,\"show_in_table\":true,\"editable\":false,\"unique\":true,\"multiline\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"users\",\"field\":{\"type\":\"boolean\",\"name\":\"disabled\",\"title\":\"Disabled\",\"show_in_form\":true,\"show_in_table\":true,\"editable\":false,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"users\",\"field\":{\"type\":\"images\",\"name\":\"avatar\",\"title\":\"Avatar\",\"show_in_form\":true,\"show_in_table\":true,\"editable\":false,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"users\",\"field\":{\"type\":\"string\",\"name\":\"password\",\"title\":\"Password\",\"show_in_form\":false,\"show_in_table\":false,\"editable\":false,\"unique\":false,\"multiline\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"users\",\"field\":{\"show_in_form\":false,\"show_in_table\":false,\"editable\":false,\"unique\":false,\"type\":\"boolean\",\"name\":\"emailVerified\",\"title\":\"Email Verified\"}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"users\",\"field\":{\"type\":\"string\",\"name\":\"emailVerificationToken\",\"title\":\"Email Verification Token\",\"show_in_form\":false,\"show_in_table\":false,\"editable\":false,\"unique\":false,\"multiline\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"users\",\"field\":{\"type\":\"datetime\",\"name\":\"emailVerificationTokenExpiresAt\",\"title\":\"Email Verification Token Expires At\",\"show_in_form\":false,\"show_in_table\":false,\"editable\":false,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"users\",\"field\":{\"type\":\"string\",\"name\":\"passwordResetToken\",\"title\":\"Password Reset Token\",\"show_in_form\":false,\"show_in_table\":false,\"editable\":false,\"unique\":false,\"multiline\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"users\",\"field\":{\"type\":\"datetime\",\"name\":\"passwordResetTokenExpiresAt\",\"title\":\"Password Reset Token Expires At\",\"show_in_form\":false,\"show_in_table\":false,\"editable\":false,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"users\",\"field\":{\"type\":\"string\",\"name\":\"provider\",\"title\":\"Provider\",\"show_in_form\":false,\"show_in_table\":false,\"editable\":false,\"unique\":false,\"multiline\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"analytics\",\"field\":{\"type\":\"relation_many\",\"name\":\"courses\",\"title\":\"Courses\",\"ref\":\"courses\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"analytics\",\"field\":{\"type\":\"relation_many\",\"name\":\"students\",\"title\":\"Students\",\"ref\":\"students\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"analytics\",\"field\":{\"type\":\"relation_many\",\"name\":\"instructors\",\"title\":\"Instructors\",\"ref\":\"instructors\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"courses\",\"field\":{\"type\":\"string\",\"name\":\"title\",\"title\":\"Title\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"courses\",\"field\":{\"type\":\"string\",\"name\":\"description\",\"title\":\"Description\",\"multiline\":true,\"wysiwygEditor\":true,\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"courses\",\"field\":{\"type\":\"relation_many\",\"name\":\"instructors\",\"title\":\"Instructors\",\"ref\":\"users\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"courses\",\"field\":{\"type\":\"relation_many\",\"name\":\"students\",\"title\":\"Students\",\"ref\":\"users\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"courses\",\"field\":{\"type\":\"relation_many\",\"name\":\"discussion_boards\",\"title\":\"DiscussionBoards\",\"ref\":\"discussion_boards\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"discussion_boards\",\"field\":{\"type\":\"string\",\"name\":\"topic\",\"title\":\"Topic\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"discussion_boards\",\"field\":{\"type\":\"relation_one\",\"name\":\"course\",\"title\":\"Course\",\"ref\":\"courses\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"enrollments\",\"field\":{\"type\":\"relation_one\",\"name\":\"student\",\"title\":\"Student\",\"ref\":\"students\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"enrollments\",\"field\":{\"type\":\"relation_one\",\"name\":\"course\",\"title\":\"Course\",\"ref\":\"courses\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"enrollments\",\"field\":{\"type\":\"enum\",\"name\":\"payment_status\",\"title\":\"PaymentStatus\",\"options\":[\"paid\",\"pending\",\"overdue\"],\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"instructors\",\"field\":{\"type\":\"string\",\"name\":\"name\",\"title\":\"Name\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"instructors\",\"field\":{\"type\":\"string\",\"name\":\"email\",\"title\":\"Email\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"instructors\",\"field\":{\"type\":\"string\",\"name\":\"qualifications\",\"title\":\"Qualifications\",\"multiline\":true,\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"instructors\",\"field\":{\"type\":\"relation_many\",\"name\":\"courses\",\"title\":\"Courses\",\"ref\":\"courses\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"students\",\"field\":{\"type\":\"string\",\"name\":\"name\",\"title\":\"Name\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"students\",\"field\":{\"type\":\"string\",\"name\":\"email\",\"title\":\"Email\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"students\",\"field\":{\"type\":\"relation_many\",\"name\":\"enrollments\",\"title\":\"Enrollments\",\"ref\":\"enrollments\",\"show_in_form\":true,\"show_in_table\":true,\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"permissions\",\"field\":{\"name\":\"name\",\"type\":\"string\",\"multiline\":false,\"wysiwygEditor\":false,\"show_in_form\":true,\"show_in_table\":true,\"editable\":false,\"title\":\"Name\",\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"roles\",\"field\":{\"name\":\"name\",\"type\":\"string\",\"multiline\":false,\"wysiwygEditor\":false,\"show_in_form\":true,\"show_in_table\":true,\"editable\":false,\"title\":\"Name\",\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"roles\",\"field\":{\"name\":\"role_customization\",\"type\":\"string\",\"multiline\":false,\"wysiwygEditor\":false,\"show_in_form\":false,\"show_in_table\":false,\"editable\":false,\"title\":\"Role Customization\",\"unique\":false}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"roles\",\"field\":{\"name\":\"permissions\",\"type\":\"relation_many\",\"show_in_form\":true,\"show_in_table\":true,\"editable\":false,\"title\":\"Permissions\",\"unique\":false,\"ref\":\"permissions\"}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"users\",\"field\":{\"name\":\"app_role\",\"type\":\"relation_one\",\"show_in_form\":true,\"show_in_table\":true,\"editable\":false,\"title\":\"App Role\",\"unique\":false,\"ref\":\"roles\"}}},{\"type\":\"field:create\",\"payload\":{\"table\":\"users\",\"field\":{\"name\":\"custom_permissions\",\"type\":\"relation_many\",\"show_in_form\":true,\"show_in_table\":true,\"editable\":false,\"title\":\"Custom Permissions\",\"unique\":false,\"ref\":\"permissions\"}}}]}],\"seeds\":[{\"time\":1744283645027,\"changes\":[{\"type\":\"create\",\"tables\":\"users\"},{\"type\":\"create\",\"tables\":\"analytics\"},{\"type\":\"create\",\"tables\":\"courses\"},{\"type\":\"create\",\"tables\":\"discussion_boards\"},{\"type\":\"create\",\"tables\":\"enrollments\"},{\"type\":\"create\",\"tables\":\"instructors\"},{\"type\":\"create\",\"tables\":\"students\"},{\"type\":\"create\",\"tables\":\"roles\"},{\"type\":\"create\",\"tables\":\"permissions\"}]}],\"frontend\":\"react\",\"backend\":\"nodejs\",\"design\":\"tailwind\",\"db\":\"postgresql\",\"title\":\"save_schema_test\",\"advanced_roles_permissions\":true,\"project_uuid\":\"c015ebf1-da8b-4884-80de-63a043cc2150\"}" -} \ No newline at end of file diff --git a/backend/src/db/api/likes.js b/backend/src/db/api/likes.js deleted file mode 100644 index 9c94362..0000000 --- a/backend/src/db/api/likes.js +++ /dev/null @@ -1,246 +0,0 @@ -const db = require('../models'); -const FileDBApi = require('./file'); -const crypto = require('crypto'); -const Utils = require('../utils'); - -const Sequelize = db.Sequelize; -const Op = Sequelize.Op; - -module.exports = class LikesDBApi { - static async create(data, options) { - const currentUser = (options && options.currentUser) || { id: null }; - const transaction = (options && options.transaction) || undefined; - - const likes = await db.likes.create( - { - id: data.id || undefined, - - amount: data.amount || null, - importHash: data.importHash || null, - createdById: currentUser.id, - updatedById: currentUser.id, - }, - { transaction }, - ); - - return likes; - } - - static async bulkImport(data, options) { - const currentUser = (options && options.currentUser) || { id: null }; - const transaction = (options && options.transaction) || undefined; - - // Prepare data - wrapping individual data transformations in a map() method - const likesData = data.map((item, index) => ({ - id: item.id || undefined, - - amount: item.amount || null, - importHash: item.importHash || null, - createdById: currentUser.id, - updatedById: currentUser.id, - createdAt: new Date(Date.now() + index * 1000), - })); - - // Bulk create items - const likes = await db.likes.bulkCreate(likesData, { transaction }); - - // For each item created, replace relation files - - return likes; - } - - static async update(id, data, options) { - const currentUser = (options && options.currentUser) || { id: null }; - const transaction = (options && options.transaction) || undefined; - - const likes = await db.likes.findByPk(id, {}, { transaction }); - - const updatePayload = {}; - - if (data.amount !== undefined) updatePayload.amount = data.amount; - - updatePayload.updatedById = currentUser.id; - - await likes.update(updatePayload, { transaction }); - - return likes; - } - - static async deleteByIds(ids, options) { - const currentUser = (options && options.currentUser) || { id: null }; - const transaction = (options && options.transaction) || undefined; - - const likes = await db.likes.findAll({ - where: { - id: { - [Op.in]: ids, - }, - }, - transaction, - }); - - await db.sequelize.transaction(async (transaction) => { - for (const record of likes) { - await record.update({ deletedBy: currentUser.id }, { transaction }); - } - for (const record of likes) { - await record.destroy({ transaction }); - } - }); - - return likes; - } - - static async remove(id, options) { - const currentUser = (options && options.currentUser) || { id: null }; - const transaction = (options && options.transaction) || undefined; - - const likes = await db.likes.findByPk(id, options); - - await likes.update( - { - deletedBy: currentUser.id, - }, - { - transaction, - }, - ); - - await likes.destroy({ - transaction, - }); - - return likes; - } - - static async findBy(where, options) { - const transaction = (options && options.transaction) || undefined; - - const likes = await db.likes.findOne({ where }, { transaction }); - - if (!likes) { - return likes; - } - - const output = likes.get({ plain: true }); - - return output; - } - - static async findAll(filter, options) { - const limit = filter.limit || 0; - let offset = 0; - let where = {}; - const currentPage = +filter.page; - - offset = currentPage * limit; - - const orderBy = null; - - const transaction = (options && options.transaction) || undefined; - - let include = []; - - if (filter) { - if (filter.id) { - where = { - ...where, - ['id']: Utils.uuid(filter.id), - }; - } - - if (filter.amount) { - where = { - ...where, - [Op.and]: Utils.ilike('likes', 'amount', filter.amount), - }; - } - - if (filter.active !== undefined) { - where = { - ...where, - active: filter.active === true || filter.active === 'true', - }; - } - - if (filter.createdAtRange) { - const [start, end] = filter.createdAtRange; - - if (start !== undefined && start !== null && start !== '') { - where = { - ...where, - ['createdAt']: { - ...where.createdAt, - [Op.gte]: start, - }, - }; - } - - if (end !== undefined && end !== null && end !== '') { - where = { - ...where, - ['createdAt']: { - ...where.createdAt, - [Op.lte]: end, - }, - }; - } - } - } - - const queryOptions = { - where, - include, - distinct: true, - order: - filter.field && filter.sort - ? [[filter.field, filter.sort]] - : [['createdAt', 'desc']], - transaction: options?.transaction, - logging: console.log, - }; - - if (!options?.countOnly) { - queryOptions.limit = limit ? Number(limit) : undefined; - queryOptions.offset = offset ? Number(offset) : undefined; - } - - try { - const { rows, count } = await db.likes.findAndCountAll(queryOptions); - - return { - rows: options?.countOnly ? [] : rows, - count: count, - }; - } catch (error) { - console.error('Error executing query:', error); - throw error; - } - } - - static async findAllAutocomplete(query, limit, offset) { - let where = {}; - - if (query) { - where = { - [Op.or]: [ - { ['id']: Utils.uuid(query) }, - Utils.ilike('likes', 'id', query), - ], - }; - } - - const records = await db.likes.findAll({ - attributes: ['id', 'id'], - where, - limit: limit ? Number(limit) : undefined, - offset: offset ? Number(offset) : undefined, - orderBy: [['id', 'ASC']], - }); - - return records.map((record) => ({ - id: record.id, - label: record.id, - })); - } -}; diff --git a/backend/src/db/migrations/1744285350750.js b/backend/src/db/migrations/1744285350750.js deleted file mode 100644 index 3ab60dc..0000000 --- a/backend/src/db/migrations/1744285350750.js +++ /dev/null @@ -1,72 +0,0 @@ -module.exports = { - /** - * @param {QueryInterface} queryInterface - * @param {Sequelize} Sequelize - * @returns {Promise} - */ - async up(queryInterface, Sequelize) { - /** - * @type {Transaction} - */ - const transaction = await queryInterface.sequelize.transaction(); - try { - await queryInterface.createTable( - 'likes', - { - id: { - type: Sequelize.DataTypes.UUID, - defaultValue: Sequelize.DataTypes.UUIDV4, - primaryKey: true, - }, - createdById: { - type: Sequelize.DataTypes.UUID, - references: { - key: 'id', - model: 'users', - }, - }, - updatedById: { - type: Sequelize.DataTypes.UUID, - references: { - key: 'id', - model: 'users', - }, - }, - createdAt: { type: Sequelize.DataTypes.DATE }, - updatedAt: { type: Sequelize.DataTypes.DATE }, - deletedAt: { type: Sequelize.DataTypes.DATE }, - importHash: { - type: Sequelize.DataTypes.STRING(255), - allowNull: true, - unique: true, - }, - }, - { transaction }, - ); - - await transaction.commit(); - } catch (err) { - await transaction.rollback(); - throw err; - } - }, - /** - * @param {QueryInterface} queryInterface - * @param {Sequelize} Sequelize - * @returns {Promise} - */ - async down(queryInterface, Sequelize) { - /** - * @type {Transaction} - */ - const transaction = await queryInterface.sequelize.transaction(); - try { - await queryInterface.dropTable('likes', { transaction }); - - await transaction.commit(); - } catch (err) { - await transaction.rollback(); - throw err; - } - }, -}; diff --git a/backend/src/db/migrations/1744285385406.js b/backend/src/db/migrations/1744285385406.js deleted file mode 100644 index 628c42f..0000000 --- a/backend/src/db/migrations/1744285385406.js +++ /dev/null @@ -1,47 +0,0 @@ -module.exports = { - /** - * @param {QueryInterface} queryInterface - * @param {Sequelize} Sequelize - * @returns {Promise} - */ - async up(queryInterface, Sequelize) { - /** - * @type {Transaction} - */ - const transaction = await queryInterface.sequelize.transaction(); - try { - await queryInterface.addColumn( - 'likes', - 'amount', - { - type: Sequelize.DataTypes.TEXT, - }, - { transaction }, - ); - - await transaction.commit(); - } catch (err) { - await transaction.rollback(); - throw err; - } - }, - /** - * @param {QueryInterface} queryInterface - * @param {Sequelize} Sequelize - * @returns {Promise} - */ - async down(queryInterface, Sequelize) { - /** - * @type {Transaction} - */ - const transaction = await queryInterface.sequelize.transaction(); - try { - await queryInterface.removeColumn('likes', 'amount', { transaction }); - - await transaction.commit(); - } catch (err) { - await transaction.rollback(); - throw err; - } - }, -}; diff --git a/backend/src/db/models/likes.js b/backend/src/db/models/likes.js deleted file mode 100644 index c5e8621..0000000 --- a/backend/src/db/models/likes.js +++ /dev/null @@ -1,49 +0,0 @@ -const config = require('../../config'); -const providers = config.providers; -const crypto = require('crypto'); -const bcrypt = require('bcrypt'); -const moment = require('moment'); - -module.exports = function (sequelize, DataTypes) { - const likes = sequelize.define( - 'likes', - { - id: { - type: DataTypes.UUID, - defaultValue: DataTypes.UUIDV4, - primaryKey: true, - }, - - amount: { - type: DataTypes.TEXT, - }, - - importHash: { - type: DataTypes.STRING(255), - allowNull: true, - unique: true, - }, - }, - { - timestamps: true, - paranoid: true, - freezeTableName: true, - }, - ); - - likes.associate = (db) => { - /// loop through entities and it's fields, and if ref === current e[name] and create relation has many on parent entity - - //end loop - - db.likes.belongsTo(db.users, { - as: 'createdBy', - }); - - db.likes.belongsTo(db.users, { - as: 'updatedBy', - }); - }; - - return likes; -}; diff --git a/backend/src/db/seeders/20200430130760-user-roles.js b/backend/src/db/seeders/20200430130760-user-roles.js index 96f97b6..54b0cb5 100644 --- a/backend/src/db/seeders/20200430130760-user-roles.js +++ b/backend/src/db/seeders/20200430130760-user-roles.js @@ -101,7 +101,6 @@ module.exports = { 'students', 'roles', 'permissions', - 'likes', , ]; await queryInterface.bulkInsert( @@ -949,31 +948,6 @@ primary key ("roles_permissionsId", "permissionId") permissionId: getId('DELETE_PERMISSIONS'), }, - { - createdAt, - updatedAt, - roles_permissionsId: getId('Administrator'), - permissionId: getId('CREATE_LIKES'), - }, - { - createdAt, - updatedAt, - roles_permissionsId: getId('Administrator'), - permissionId: getId('READ_LIKES'), - }, - { - createdAt, - updatedAt, - roles_permissionsId: getId('Administrator'), - permissionId: getId('UPDATE_LIKES'), - }, - { - createdAt, - updatedAt, - roles_permissionsId: getId('Administrator'), - permissionId: getId('DELETE_LIKES'), - }, - { createdAt, updatedAt, diff --git a/backend/src/db/seeders/20231127130745-sample-data.js b/backend/src/db/seeders/20231127130745-sample-data.js index bfa1953..10b658c 100644 --- a/backend/src/db/seeders/20231127130745-sample-data.js +++ b/backend/src/db/seeders/20231127130745-sample-data.js @@ -13,8 +13,6 @@ const Instructors = db.instructors; const Students = db.students; -const Likes = db.likes; - const AnalyticsData = [ { // type code here for "relation_many" field @@ -33,18 +31,6 @@ const AnalyticsData = [ // type code here for "relation_many" field // type code here for "relation_many" field }, - - { - // type code here for "relation_many" field - // type code here for "relation_many" field - // type code here for "relation_many" field - }, - - { - // type code here for "relation_many" field - // type code here for "relation_many" field - // type code here for "relation_many" field - }, ]; const CoursesData = [ @@ -83,30 +69,6 @@ const CoursesData = [ // type code here for "relation_many" field }, - - { - title: 'Graphic Design', - - description: 'Develop skills in design software and visual communication.', - - // type code here for "relation_many" field - - // type code here for "relation_many" field - - // type code here for "relation_many" field - }, - - { - title: 'Business Management', - - description: 'Understand the fundamentals of managing a business.', - - // type code here for "relation_many" field - - // type code here for "relation_many" field - - // type code here for "relation_many" field - }, ]; const DiscussionBoardsData = [ @@ -127,18 +89,6 @@ const DiscussionBoardsData = [ // type code here for "relation_one" field }, - - { - topic: 'Design Trends', - - // type code here for "relation_one" field - }, - - { - topic: 'Leadership Skills', - - // type code here for "relation_one" field - }, ]; const EnrollmentsData = [ @@ -147,7 +97,7 @@ const EnrollmentsData = [ // type code here for "relation_one" field - payment_status: 'pending', + payment_status: 'paid', }, { @@ -165,22 +115,6 @@ const EnrollmentsData = [ payment_status: 'pending', }, - - { - // type code here for "relation_one" field - - // type code here for "relation_one" field - - payment_status: 'pending', - }, - - { - // type code here for "relation_one" field - - // type code here for "relation_one" field - - payment_status: 'paid', - }, ]; const InstructorsData = [ @@ -213,26 +147,6 @@ const InstructorsData = [ // type code here for "relation_many" field }, - - { - name: 'Mr. Michael Green', - - email: 'michael.green@example.com', - - qualifications: 'MSc in Mathematics', - - // type code here for "relation_many" field - }, - - { - name: 'Dr. Olivia White', - - email: 'olivia.white@example.com', - - qualifications: 'PhD in Marketing', - - // type code here for "relation_many" field - }, ]; const StudentsData = [ @@ -259,44 +173,6 @@ const StudentsData = [ // type code here for "relation_many" field }, - - { - name: 'Diana Prince', - - email: 'diana.prince@example.com', - - // type code here for "relation_many" field - }, - - { - name: 'Ethan Hunt', - - email: 'ethan.hunt@example.com', - - // type code here for "relation_many" field - }, -]; - -const LikesData = [ - { - amount: 'Noam Chomsky', - }, - - { - amount: 'Jonas Salk', - }, - - { - amount: 'Comte de Buffon', - }, - - { - amount: 'Gertrude Belle Elion', - }, - - { - amount: 'Jean Baptiste Lamarck', - }, ]; // Similar logic for "relation_many" @@ -346,28 +222,6 @@ async function associateDiscussionBoardWithCourse() { if (DiscussionBoard2?.setCourse) { await DiscussionBoard2.setCourse(relatedCourse2); } - - const relatedCourse3 = await Courses.findOne({ - offset: Math.floor(Math.random() * (await Courses.count())), - }); - const DiscussionBoard3 = await DiscussionBoards.findOne({ - order: [['id', 'ASC']], - offset: 3, - }); - if (DiscussionBoard3?.setCourse) { - await DiscussionBoard3.setCourse(relatedCourse3); - } - - const relatedCourse4 = await Courses.findOne({ - offset: Math.floor(Math.random() * (await Courses.count())), - }); - const DiscussionBoard4 = await DiscussionBoards.findOne({ - order: [['id', 'ASC']], - offset: 4, - }); - if (DiscussionBoard4?.setCourse) { - await DiscussionBoard4.setCourse(relatedCourse4); - } } async function associateEnrollmentWithStudent() { @@ -403,28 +257,6 @@ async function associateEnrollmentWithStudent() { if (Enrollment2?.setStudent) { await Enrollment2.setStudent(relatedStudent2); } - - const relatedStudent3 = await Students.findOne({ - offset: Math.floor(Math.random() * (await Students.count())), - }); - const Enrollment3 = await Enrollments.findOne({ - order: [['id', 'ASC']], - offset: 3, - }); - if (Enrollment3?.setStudent) { - await Enrollment3.setStudent(relatedStudent3); - } - - const relatedStudent4 = await Students.findOne({ - offset: Math.floor(Math.random() * (await Students.count())), - }); - const Enrollment4 = await Enrollments.findOne({ - order: [['id', 'ASC']], - offset: 4, - }); - if (Enrollment4?.setStudent) { - await Enrollment4.setStudent(relatedStudent4); - } } async function associateEnrollmentWithCourse() { @@ -460,28 +292,6 @@ async function associateEnrollmentWithCourse() { if (Enrollment2?.setCourse) { await Enrollment2.setCourse(relatedCourse2); } - - const relatedCourse3 = await Courses.findOne({ - offset: Math.floor(Math.random() * (await Courses.count())), - }); - const Enrollment3 = await Enrollments.findOne({ - order: [['id', 'ASC']], - offset: 3, - }); - if (Enrollment3?.setCourse) { - await Enrollment3.setCourse(relatedCourse3); - } - - const relatedCourse4 = await Courses.findOne({ - offset: Math.floor(Math.random() * (await Courses.count())), - }); - const Enrollment4 = await Enrollments.findOne({ - order: [['id', 'ASC']], - offset: 4, - }); - if (Enrollment4?.setCourse) { - await Enrollment4.setCourse(relatedCourse4); - } } // Similar logic for "relation_many" @@ -502,8 +312,6 @@ module.exports = { await Students.bulkCreate(StudentsData); - await Likes.bulkCreate(LikesData); - await Promise.all([ // Similar logic for "relation_many" @@ -543,7 +351,5 @@ module.exports = { await queryInterface.bulkDelete('instructors', null, {}); await queryInterface.bulkDelete('students', null, {}); - - await queryInterface.bulkDelete('likes', null, {}); }, }; diff --git a/backend/src/db/seeders/20250410114230.js b/backend/src/db/seeders/20250410114230.js deleted file mode 100644 index ddd1a6e..0000000 --- a/backend/src/db/seeders/20250410114230.js +++ /dev/null @@ -1,87 +0,0 @@ -const { v4: uuid } = require('uuid'); -const db = require('../models'); -const Sequelize = require('sequelize'); -const config = require('../../config'); - -module.exports = { - /** - * @param{import("sequelize").QueryInterface} queryInterface - * @return {Promise} - */ - async up(queryInterface) { - const createdAt = new Date(); - const updatedAt = new Date(); - - /** @type {Map} */ - const idMap = new Map(); - - /** - * @param {string} key - * @return {string} - */ - function getId(key) { - if (idMap.has(key)) { - return idMap.get(key); - } - const id = uuid(); - idMap.set(key, id); - return id; - } - - /** - * @param {string} name - */ - function createPermissions(name) { - return [ - { - id: getId(`CREATE_${name.toUpperCase()}`), - createdAt, - updatedAt, - name: `CREATE_${name.toUpperCase()}`, - }, - { - id: getId(`READ_${name.toUpperCase()}`), - createdAt, - updatedAt, - name: `READ_${name.toUpperCase()}`, - }, - { - id: getId(`UPDATE_${name.toUpperCase()}`), - createdAt, - updatedAt, - name: `UPDATE_${name.toUpperCase()}`, - }, - { - id: getId(`DELETE_${name.toUpperCase()}`), - createdAt, - updatedAt, - name: `DELETE_${name.toUpperCase()}`, - }, - ]; - } - - const entities = ['likes']; - - const createdPermissions = entities.flatMap(createPermissions); - - // Add permissions to database - await queryInterface.bulkInsert('permissions', createdPermissions); - // Get permissions ids - const permissionsIds = createdPermissions.map((p) => p.id); - // Get admin role - const adminRole = await db.roles.findOne({ - where: { name: config.roles.admin }, - }); - - if (adminRole) { - // Add permissions to admin role if it exists - await adminRole.addPermissions(permissionsIds); - } - }, - down: async (queryInterface, Sequelize) => { - await queryInterface.bulkDelete( - 'permissions', - entities.flatMap(createPermissions), - ); - }, -}; diff --git a/backend/src/index.js b/backend/src/index.js index 2a90fd2..b0518da 100644 --- a/backend/src/index.js +++ b/backend/src/index.js @@ -37,8 +37,6 @@ const rolesRoutes = require('./routes/roles'); const permissionsRoutes = require('./routes/permissions'); -const likesRoutes = require('./routes/likes'); - const getBaseUrl = (url) => { if (!url) return ''; return url.endsWith('/api') ? url.slice(0, -4) : url; @@ -49,9 +47,9 @@ const options = { openapi: '3.0.0', info: { version: '1.0.0', - title: 'save_schema_test', + title: 'saveschematest', description: - 'save_schema_test Online REST API for Testing and Prototyping application. You can perform all major operations with your entities - create, delete and etc.', + 'saveschematest Online REST API for Testing and Prototyping application. You can perform all major operations with your entities - create, delete and etc.', }, servers: [ { @@ -158,12 +156,6 @@ app.use( permissionsRoutes, ); -app.use( - '/api/likes', - passport.authenticate('jwt', { session: false }), - likesRoutes, -); - app.use( '/api/openai', passport.authenticate('jwt', { session: false }), diff --git a/backend/src/routes/likes.js b/backend/src/routes/likes.js deleted file mode 100644 index f6033ff..0000000 --- a/backend/src/routes/likes.js +++ /dev/null @@ -1,433 +0,0 @@ -const express = require('express'); - -const LikesService = require('../services/likes'); -const LikesDBApi = require('../db/api/likes'); -const wrapAsync = require('../helpers').wrapAsync; - -const router = express.Router(); - -const { parse } = require('json2csv'); - -const { checkCrudPermissions } = require('../middlewares/check-permissions'); - -router.use(checkCrudPermissions('likes')); - -/** - * @swagger - * components: - * schemas: - * Likes: - * type: object - * properties: - - * amount: - * type: string - * default: amount - - */ - -/** - * @swagger - * tags: - * name: Likes - * description: The Likes managing API - */ - -/** - * @swagger - * /api/likes: - * post: - * security: - * - bearerAuth: [] - * tags: [Likes] - * summary: Add new item - * description: Add new item - * requestBody: - * required: true - * content: - * application/json: - * schema: - * properties: - * data: - * description: Data of the updated item - * type: object - * $ref: "#/components/schemas/Likes" - * responses: - * 200: - * description: The item was successfully added - * content: - * application/json: - * schema: - * $ref: "#/components/schemas/Likes" - * 401: - * $ref: "#/components/responses/UnauthorizedError" - * 405: - * description: Invalid input data - * 500: - * description: Some server error - */ -router.post( - '/', - wrapAsync(async (req, res) => { - const referer = - req.headers.referer || - `${req.protocol}://${req.hostname}${req.originalUrl}`; - const link = new URL(referer); - await LikesService.create(req.body.data, req.currentUser, true, link.host); - const payload = true; - res.status(200).send(payload); - }), -); - -/** - * @swagger - * /api/budgets/bulk-import: - * post: - * security: - * - bearerAuth: [] - * tags: [Likes] - * summary: Bulk import items - * description: Bulk import items - * requestBody: - * required: true - * content: - * application/json: - * schema: - * properties: - * data: - * description: Data of the updated items - * type: array - * items: - * $ref: "#/components/schemas/Likes" - * responses: - * 200: - * description: The items were successfully imported - * content: - * application/json: - * schema: - * $ref: "#/components/schemas/Likes" - * 401: - * $ref: "#/components/responses/UnauthorizedError" - * 405: - * description: Invalid input data - * 500: - * description: Some server error - * - */ -router.post( - '/bulk-import', - wrapAsync(async (req, res) => { - const referer = - req.headers.referer || - `${req.protocol}://${req.hostname}${req.originalUrl}`; - const link = new URL(referer); - await LikesService.bulkImport(req, res, true, link.host); - const payload = true; - res.status(200).send(payload); - }), -); - -/** - * @swagger - * /api/likes/{id}: - * put: - * security: - * - bearerAuth: [] - * tags: [Likes] - * summary: Update the data of the selected item - * description: Update the data of the selected item - * parameters: - * - in: path - * name: id - * description: Item ID to update - * required: true - * schema: - * type: string - * requestBody: - * description: Set new item data - * required: true - * content: - * application/json: - * schema: - * properties: - * id: - * description: ID of the updated item - * type: string - * data: - * description: Data of the updated item - * type: object - * $ref: "#/components/schemas/Likes" - * required: - * - id - * responses: - * 200: - * description: The item data was successfully updated - * content: - * application/json: - * schema: - * $ref: "#/components/schemas/Likes" - * 400: - * description: Invalid ID supplied - * 401: - * $ref: "#/components/responses/UnauthorizedError" - * 404: - * description: Item not found - * 500: - * description: Some server error - */ -router.put( - '/:id', - wrapAsync(async (req, res) => { - await LikesService.update(req.body.data, req.body.id, req.currentUser); - const payload = true; - res.status(200).send(payload); - }), -); - -/** - * @swagger - * /api/likes/{id}: - * delete: - * security: - * - bearerAuth: [] - * tags: [Likes] - * summary: Delete the selected item - * description: Delete the selected item - * parameters: - * - in: path - * name: id - * description: Item ID to delete - * required: true - * schema: - * type: string - * responses: - * 200: - * description: The item was successfully deleted - * content: - * application/json: - * schema: - * $ref: "#/components/schemas/Likes" - * 400: - * description: Invalid ID supplied - * 401: - * $ref: "#/components/responses/UnauthorizedError" - * 404: - * description: Item not found - * 500: - * description: Some server error - */ -router.delete( - '/:id', - wrapAsync(async (req, res) => { - await LikesService.remove(req.params.id, req.currentUser); - const payload = true; - res.status(200).send(payload); - }), -); - -/** - * @swagger - * /api/likes/deleteByIds: - * post: - * security: - * - bearerAuth: [] - * tags: [Likes] - * summary: Delete the selected item list - * description: Delete the selected item list - * requestBody: - * required: true - * content: - * application/json: - * schema: - * properties: - * ids: - * description: IDs of the updated items - * type: array - * responses: - * 200: - * description: The items was successfully deleted - * content: - * application/json: - * schema: - * $ref: "#/components/schemas/Likes" - * 401: - * $ref: "#/components/responses/UnauthorizedError" - * 404: - * description: Items not found - * 500: - * description: Some server error - */ -router.post( - '/deleteByIds', - wrapAsync(async (req, res) => { - await LikesService.deleteByIds(req.body.data, req.currentUser); - const payload = true; - res.status(200).send(payload); - }), -); - -/** - * @swagger - * /api/likes: - * get: - * security: - * - bearerAuth: [] - * tags: [Likes] - * summary: Get all likes - * description: Get all likes - * responses: - * 200: - * description: Likes list successfully received - * content: - * application/json: - * schema: - * type: array - * items: - * $ref: "#/components/schemas/Likes" - * 401: - * $ref: "#/components/responses/UnauthorizedError" - * 404: - * description: Data not found - * 500: - * description: Some server error - */ -router.get( - '/', - wrapAsync(async (req, res) => { - const filetype = req.query.filetype; - - const currentUser = req.currentUser; - const payload = await LikesDBApi.findAll(req.query, { currentUser }); - if (filetype && filetype === 'csv') { - const fields = ['id', 'amount']; - const opts = { fields }; - try { - const csv = parse(payload.rows, opts); - res.status(200).attachment(csv); - res.send(csv); - } catch (err) { - console.error(err); - } - } else { - res.status(200).send(payload); - } - }), -); - -/** - * @swagger - * /api/likes/count: - * get: - * security: - * - bearerAuth: [] - * tags: [Likes] - * summary: Count all likes - * description: Count all likes - * responses: - * 200: - * description: Likes count successfully received - * content: - * application/json: - * schema: - * type: array - * items: - * $ref: "#/components/schemas/Likes" - * 401: - * $ref: "#/components/responses/UnauthorizedError" - * 404: - * description: Data not found - * 500: - * description: Some server error - */ -router.get( - '/count', - wrapAsync(async (req, res) => { - const currentUser = req.currentUser; - const payload = await LikesDBApi.findAll(req.query, null, { - countOnly: true, - currentUser, - }); - - res.status(200).send(payload); - }), -); - -/** - * @swagger - * /api/likes/autocomplete: - * get: - * security: - * - bearerAuth: [] - * tags: [Likes] - * summary: Find all likes that match search criteria - * description: Find all likes that match search criteria - * responses: - * 200: - * description: Likes list successfully received - * content: - * application/json: - * schema: - * type: array - * items: - * $ref: "#/components/schemas/Likes" - * 401: - * $ref: "#/components/responses/UnauthorizedError" - * 404: - * description: Data not found - * 500: - * description: Some server error - */ -router.get('/autocomplete', async (req, res) => { - const payload = await LikesDBApi.findAllAutocomplete( - req.query.query, - req.query.limit, - req.query.offset, - ); - - res.status(200).send(payload); -}); - -/** - * @swagger - * /api/likes/{id}: - * get: - * security: - * - bearerAuth: [] - * tags: [Likes] - * summary: Get selected item - * description: Get selected item - * parameters: - * - in: path - * name: id - * description: ID of item to get - * required: true - * schema: - * type: string - * responses: - * 200: - * description: Selected item successfully received - * content: - * application/json: - * schema: - * $ref: "#/components/schemas/Likes" - * 400: - * description: Invalid ID supplied - * 401: - * $ref: "#/components/responses/UnauthorizedError" - * 404: - * description: Item not found - * 500: - * description: Some server error - */ -router.get( - '/:id', - wrapAsync(async (req, res) => { - const payload = await LikesDBApi.findBy({ id: req.params.id }); - - res.status(200).send(payload); - }), -); - -router.use('/', require('../helpers').commonErrorHandler); - -module.exports = router; diff --git a/backend/src/services/likes.js b/backend/src/services/likes.js deleted file mode 100644 index d8f6f3e..0000000 --- a/backend/src/services/likes.js +++ /dev/null @@ -1,114 +0,0 @@ -const db = require('../db/models'); -const LikesDBApi = require('../db/api/likes'); -const processFile = require('../middlewares/upload'); -const ValidationError = require('./notifications/errors/validation'); -const csv = require('csv-parser'); -const axios = require('axios'); -const config = require('../config'); -const stream = require('stream'); - -module.exports = class LikesService { - static async create(data, currentUser) { - const transaction = await db.sequelize.transaction(); - try { - await LikesDBApi.create(data, { - currentUser, - transaction, - }); - - await transaction.commit(); - } catch (error) { - await transaction.rollback(); - throw error; - } - } - - static async bulkImport(req, res, sendInvitationEmails = true, host) { - const transaction = await db.sequelize.transaction(); - - try { - await processFile(req, res); - const bufferStream = new stream.PassThrough(); - const results = []; - - await bufferStream.end(Buffer.from(req.file.buffer, 'utf-8')); // convert Buffer to Stream - - await new Promise((resolve, reject) => { - bufferStream - .pipe(csv()) - .on('data', (data) => results.push(data)) - .on('end', async () => { - console.log('CSV results', results); - resolve(); - }) - .on('error', (error) => reject(error)); - }); - - await LikesDBApi.bulkImport(results, { - transaction, - ignoreDuplicates: true, - validate: true, - currentUser: req.currentUser, - }); - - await transaction.commit(); - } catch (error) { - await transaction.rollback(); - throw error; - } - } - - static async update(data, id, currentUser) { - const transaction = await db.sequelize.transaction(); - try { - let likes = await LikesDBApi.findBy({ id }, { transaction }); - - if (!likes) { - throw new ValidationError('likesNotFound'); - } - - const updatedLikes = await LikesDBApi.update(id, data, { - currentUser, - transaction, - }); - - await transaction.commit(); - return updatedLikes; - } catch (error) { - await transaction.rollback(); - throw error; - } - } - - static async deleteByIds(ids, currentUser) { - const transaction = await db.sequelize.transaction(); - - try { - await LikesDBApi.deleteByIds(ids, { - currentUser, - transaction, - }); - - await transaction.commit(); - } catch (error) { - await transaction.rollback(); - throw error; - } - } - - static async remove(id, currentUser) { - const transaction = await db.sequelize.transaction(); - - try { - await LikesDBApi.remove(id, { - currentUser, - transaction, - }); - - await transaction.commit(); - } catch (error) { - await transaction.rollback(); - throw error; - } - } -}; diff --git a/backend/src/services/search.js b/backend/src/services/search.js index 246ec8a..4b398c4 100644 --- a/backend/src/services/search.js +++ b/backend/src/services/search.js @@ -50,8 +50,6 @@ module.exports = class SearchService { instructors: ['name', 'email', 'qualifications'], students: ['name', 'email'], - - likes: ['amount'], }; const columnsInt = {}; diff --git a/frontend/json/runtimeError.json b/frontend/json/runtimeError.json deleted file mode 100644 index 9e26dfe..0000000 --- a/frontend/json/runtimeError.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/frontend/src/components/Likes/CardLikes.tsx b/frontend/src/components/Likes/CardLikes.tsx deleted file mode 100644 index c068030..0000000 --- a/frontend/src/components/Likes/CardLikes.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import React from 'react'; -import ImageField from '../ImageField'; -import ListActionsPopover from '../ListActionsPopover'; -import { useAppSelector } from '../../stores/hooks'; -import dataFormatter from '../../helpers/dataFormatter'; -import { Pagination } from '../Pagination'; -import { saveFile } from '../../helpers/fileSaver'; -import LoadingSpinner from '../LoadingSpinner'; -import Link from 'next/link'; - -import { hasPermission } from '../../helpers/userPermissions'; - -type Props = { - likes: any[]; - loading: boolean; - onDelete: (id: string) => void; - currentPage: number; - numPages: number; - onPageChange: (page: number) => void; -}; - -const CardLikes = ({ - likes, - loading, - onDelete, - currentPage, - numPages, - onPageChange, -}: Props) => { - const asideScrollbarsStyle = useAppSelector( - (state) => state.style.asideScrollbarsStyle, - ); - const bgColor = useAppSelector((state) => state.style.cardsColor); - const darkMode = useAppSelector((state) => state.style.darkMode); - const corners = useAppSelector((state) => state.style.corners); - const focusRing = useAppSelector((state) => state.style.focusRingColor); - - const currentUser = useAppSelector((state) => state.auth.currentUser); - const hasUpdatePermission = hasPermission(currentUser, 'UPDATE_LIKES'); - - return ( -
- {loading && } -
    - {!loading && - likes.map((item, index) => ( -
  • -
    - - {item.id} - - -
    - -
    -
    -
    -
    -
    - Amount -
    -
    -
    - {item.amount} -
    -
    -
    -
    -
  • - ))} - {!loading && likes.length === 0 && ( -
    -

    No data to display

    -
    - )} -
-
- -
-
- ); -}; - -export default CardLikes; diff --git a/frontend/src/components/Likes/ListLikes.tsx b/frontend/src/components/Likes/ListLikes.tsx deleted file mode 100644 index 96ce7a4..0000000 --- a/frontend/src/components/Likes/ListLikes.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import React from 'react'; -import CardBox from '../CardBox'; -import ImageField from '../ImageField'; -import dataFormatter from '../../helpers/dataFormatter'; -import { saveFile } from '../../helpers/fileSaver'; -import ListActionsPopover from '../ListActionsPopover'; -import { useAppSelector } from '../../stores/hooks'; -import { Pagination } from '../Pagination'; -import LoadingSpinner from '../LoadingSpinner'; -import Link from 'next/link'; - -import { hasPermission } from '../../helpers/userPermissions'; - -type Props = { - likes: any[]; - loading: boolean; - onDelete: (id: string) => void; - currentPage: number; - numPages: number; - onPageChange: (page: number) => void; -}; - -const ListLikes = ({ - likes, - loading, - onDelete, - currentPage, - numPages, - onPageChange, -}: Props) => { - const currentUser = useAppSelector((state) => state.auth.currentUser); - const hasUpdatePermission = hasPermission(currentUser, 'UPDATE_LIKES'); - - const corners = useAppSelector((state) => state.style.corners); - const bgColor = useAppSelector((state) => state.style.cardsColor); - - return ( - <> -
- {loading && } - {!loading && - likes.map((item) => ( - -
- dark:divide-dark-700 overflow-x-auto' - } - > -
-

Amount

-

{item.amount}

-
- - -
-
- ))} - {!loading && likes.length === 0 && ( -
-

No data to display

-
- )} -
-
- -
- - ); -}; - -export default ListLikes; diff --git a/frontend/src/components/Likes/TableLikes.tsx b/frontend/src/components/Likes/TableLikes.tsx deleted file mode 100644 index e544926..0000000 --- a/frontend/src/components/Likes/TableLikes.tsx +++ /dev/null @@ -1,481 +0,0 @@ -import React, { useEffect, useState, useMemo } from 'react'; -import { createPortal } from 'react-dom'; -import { ToastContainer, toast } from 'react-toastify'; -import BaseButton from '../BaseButton'; -import CardBoxModal from '../CardBoxModal'; -import CardBox from '../CardBox'; -import { - fetch, - update, - deleteItem, - setRefetch, - deleteItemsByIds, -} from '../../stores/likes/likesSlice'; -import { useAppDispatch, useAppSelector } from '../../stores/hooks'; -import { useRouter } from 'next/router'; -import { Field, Form, Formik } from 'formik'; -import { DataGrid, GridColDef } from '@mui/x-data-grid'; -import { loadColumns } from './configureLikesCols'; -import _ from 'lodash'; -import dataFormatter from '../../helpers/dataFormatter'; -import { dataGridStyles } from '../../styles'; - -const perPage = 10; - -const TableSampleLikes = ({ - filterItems, - setFilterItems, - filters, - showGrid, -}) => { - const notify = (type, msg) => toast(msg, { type, position: 'bottom-center' }); - - const dispatch = useAppDispatch(); - const router = useRouter(); - - const pagesList = []; - const [id, setId] = useState(null); - const [currentPage, setCurrentPage] = useState(0); - const [filterRequest, setFilterRequest] = React.useState(''); - const [columns, setColumns] = useState([]); - const [selectedRows, setSelectedRows] = useState([]); - const [sortModel, setSortModel] = useState([ - { - field: '', - sort: 'desc', - }, - ]); - - const { - likes, - loading, - count, - notify: likesNotify, - refetch, - } = useAppSelector((state) => state.likes); - const { currentUser } = useAppSelector((state) => state.auth); - const focusRing = useAppSelector((state) => state.style.focusRingColor); - const bgColor = useAppSelector((state) => state.style.bgLayoutColor); - const corners = useAppSelector((state) => state.style.corners); - const numPages = - Math.floor(count / perPage) === 0 ? 1 : Math.ceil(count / perPage); - for (let i = 0; i < numPages; i++) { - pagesList.push(i); - } - - const loadData = async (page = currentPage, request = filterRequest) => { - if (page !== currentPage) setCurrentPage(page); - if (request !== filterRequest) setFilterRequest(request); - const { sort, field } = sortModel[0]; - - const query = `?page=${page}&limit=${perPage}${request}&sort=${sort}&field=${field}`; - dispatch(fetch({ limit: perPage, page, query })); - }; - - useEffect(() => { - if (likesNotify.showNotification) { - notify(likesNotify.typeNotification, likesNotify.textNotification); - } - }, [likesNotify.showNotification]); - - useEffect(() => { - if (!currentUser) return; - loadData(); - }, [sortModel, currentUser]); - - useEffect(() => { - if (refetch) { - loadData(0); - dispatch(setRefetch(false)); - } - }, [refetch, dispatch]); - - const [isModalInfoActive, setIsModalInfoActive] = useState(false); - const [isModalTrashActive, setIsModalTrashActive] = useState(false); - - const handleModalAction = () => { - setIsModalInfoActive(false); - setIsModalTrashActive(false); - }; - - const handleDeleteModalAction = (id: string) => { - setId(id); - setIsModalTrashActive(true); - }; - const handleDeleteAction = async () => { - if (id) { - await dispatch(deleteItem(id)); - await loadData(0); - setIsModalTrashActive(false); - } - }; - - const generateFilterRequests = useMemo(() => { - let request = '&'; - filterItems.forEach((item) => { - const isRangeFilter = filters.find( - (filter) => - filter.title === item.fields.selectedField && - (filter.number || filter.date), - ); - - if (isRangeFilter) { - const from = item.fields.filterValueFrom; - const to = item.fields.filterValueTo; - if (from) { - request += `${item.fields.selectedField}Range=${from}&`; - } - if (to) { - request += `${item.fields.selectedField}Range=${to}&`; - } - } else { - const value = item.fields.filterValue; - if (value) { - request += `${item.fields.selectedField}=${value}&`; - } - } - }); - return request; - }, [filterItems, filters]); - - const deleteFilter = (value) => { - const newItems = filterItems.filter((item) => item.id !== value); - - if (newItems.length) { - setFilterItems(newItems); - } else { - loadData(0, ''); - - setFilterItems(newItems); - } - }; - - const handleSubmit = () => { - loadData(0, generateFilterRequests); - }; - - const handleChange = (id) => (e) => { - const value = e.target.value; - const name = e.target.name; - - setFilterItems( - filterItems.map((item) => { - if (item.id !== id) return item; - if (name === 'selectedField') return { id, fields: { [name]: value } }; - - return { id, fields: { ...item.fields, [name]: value } }; - }), - ); - }; - - const handleReset = () => { - setFilterItems([]); - loadData(0, ''); - }; - - const onPageChange = (page: number) => { - loadData(page); - setCurrentPage(page); - }; - - useEffect(() => { - if (!currentUser) return; - - loadColumns(handleDeleteModalAction, `likes`, currentUser).then((newCols) => - setColumns(newCols), - ); - }, [currentUser]); - - const handleTableSubmit = async (id: string, data) => { - if (!_.isEmpty(data)) { - await dispatch(update({ id, data })) - .unwrap() - .then((res) => res) - .catch((err) => { - throw new Error(err); - }); - } - }; - - const onDeleteRows = async (selectedRows) => { - await dispatch(deleteItemsByIds(selectedRows)); - await loadData(0); - }; - - const controlClasses = - 'w-full py-2 px-2 my-2 rounded dark:placeholder-gray-400 ' + - ` ${bgColor} ${focusRing} ${corners} ` + - 'dark:bg-slate-800 border'; - - const dataGrid = ( -
- `datagrid--row`} - rows={likes ?? []} - columns={columns} - initialState={{ - pagination: { - paginationModel: { - pageSize: 10, - }, - }, - }} - disableRowSelectionOnClick - onProcessRowUpdateError={(params) => { - console.log('Error', params); - }} - processRowUpdate={async (newRow, oldRow) => { - const data = dataFormatter.dataGridEditFormatter(newRow); - - try { - await handleTableSubmit(newRow.id, data); - return newRow; - } catch { - return oldRow; - } - }} - sortingMode={'server'} - checkboxSelection - onRowSelectionModelChange={(ids) => { - setSelectedRows(ids); - }} - onSortModelChange={(params) => { - params.length - ? setSortModel(params) - : setSortModel([{ field: '', sort: 'desc' }]); - }} - rowCount={count} - pageSizeOptions={[10]} - paginationMode={'server'} - loading={loading} - onPaginationModelChange={(params) => { - onPageChange(params.page); - }} - /> -
- ); - - return ( - <> - {filterItems && Array.isArray(filterItems) && filterItems.length ? ( - - null} - > -
- <> - {filterItems && - filterItems.map((filterItem) => { - return ( -
-
-
- Filter -
- - {filters.map((selectOption) => ( - - ))} - -
- {filters.find( - (filter) => - filter.title === filterItem?.fields?.selectedField, - )?.type === 'enum' ? ( -
-
Value
- - - {filters - .find( - (filter) => - filter.title === - filterItem?.fields?.selectedField, - ) - ?.options?.map((option) => ( - - ))} - -
- ) : filters.find( - (filter) => - filter.title === - filterItem?.fields?.selectedField, - )?.number ? ( -
-
-
- From -
- -
-
-
- To -
- -
-
- ) : filters.find( - (filter) => - filter.title === - filterItem?.fields?.selectedField, - )?.date ? ( -
-
-
- From -
- -
-
-
- To -
- -
-
- ) : ( -
-
- Contains -
- -
- )} -
-
- Action -
- { - deleteFilter(filterItem.id); - }} - /> -
-
- ); - })} -
- - -
- -
-
-
- ) : null} - -

Are you sure you want to delete this item?

-
- - {dataGrid} - - {selectedRows.length > 0 && - createPortal( - onDeleteRows(selectedRows)} - />, - document.getElementById('delete-rows-button'), - )} - - - ); -}; - -export default TableSampleLikes; diff --git a/frontend/src/components/Likes/configureLikesCols.tsx b/frontend/src/components/Likes/configureLikesCols.tsx deleted file mode 100644 index 1986c44..0000000 --- a/frontend/src/components/Likes/configureLikesCols.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React from 'react'; -import BaseIcon from '../BaseIcon'; -import { mdiEye, mdiTrashCan, mdiPencilOutline } from '@mdi/js'; -import axios from 'axios'; -import { - GridActionsCellItem, - GridRowParams, - GridValueGetterParams, -} from '@mui/x-data-grid'; -import ImageField from '../ImageField'; -import { saveFile } from '../../helpers/fileSaver'; -import dataFormatter from '../../helpers/dataFormatter'; -import DataGridMultiSelect from '../DataGridMultiSelect'; -import ListActionsPopover from '../ListActionsPopover'; - -import { hasPermission } from '../../helpers/userPermissions'; - -type Params = (id: string) => void; - -export const loadColumns = async ( - onDelete: Params, - entityName: string, - - user, -) => { - async function callOptionsApi(entityName: string) { - if (!hasPermission(user, 'READ_' + entityName.toUpperCase())) return []; - - try { - const data = await axios(`/${entityName}/autocomplete?limit=100`); - return data.data; - } catch (error) { - console.log(error); - return []; - } - } - - const hasUpdatePermission = hasPermission(user, 'UPDATE_LIKES'); - - return [ - { - field: 'amount', - headerName: 'Amount', - flex: 1, - minWidth: 120, - filterable: false, - headerClassName: 'datagrid--header', - cellClassName: 'datagrid--cell', - - editable: hasUpdatePermission, - }, - - { - field: 'actions', - type: 'actions', - minWidth: 30, - headerClassName: 'datagrid--header', - cellClassName: 'datagrid--cell', - getActions: (params: GridRowParams) => { - return [ - , - ]; - }, - }, - ]; -}; diff --git a/frontend/src/menuAside.ts b/frontend/src/menuAside.ts index e9ebe8e..3a41f9c 100644 --- a/frontend/src/menuAside.ts +++ b/frontend/src/menuAside.ts @@ -88,14 +88,6 @@ const menuAside: MenuAsideItem[] = [ : icon.mdiTable, permissions: 'READ_PERMISSIONS', }, - { - href: '/likes/likes-list', - label: 'Likes', - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - icon: icon.mdiTable ? icon.mdiTable : icon.mdiTable, - permissions: 'READ_LIKES', - }, { href: '/profile', label: 'Profile', diff --git a/frontend/src/pages/dashboard.tsx b/frontend/src/pages/dashboard.tsx index 965aaca..25be6e2 100644 --- a/frontend/src/pages/dashboard.tsx +++ b/frontend/src/pages/dashboard.tsx @@ -32,7 +32,6 @@ const Dashboard = () => { const [students, setStudents] = React.useState('Loading...'); const [roles, setRoles] = React.useState('Loading...'); const [permissions, setPermissions] = React.useState('Loading...'); - const [likes, setLikes] = React.useState('Loading...'); const [widgetsRole, setWidgetsRole] = React.useState({ role: { value: '', label: '' }, @@ -53,7 +52,6 @@ const Dashboard = () => { 'students', 'roles', 'permissions', - 'likes', ]; const fns = [ setUsers, @@ -65,7 +63,6 @@ const Dashboard = () => { setStudents, setRoles, setPermissions, - setLikes, ]; const requests = entities.map((entity, index) => { @@ -461,38 +458,6 @@ const Dashboard = () => { )} - - {hasPermission(currentUser, 'READ_LIKES') && ( - -
-
-
-
- Likes -
-
- {likes} -
-
-
- -
-
-
- - )} diff --git a/frontend/src/pages/likes/[likesId].tsx b/frontend/src/pages/likes/[likesId].tsx deleted file mode 100644 index 5c542f6..0000000 --- a/frontend/src/pages/likes/[likesId].tsx +++ /dev/null @@ -1,124 +0,0 @@ -import { mdiChartTimelineVariant, mdiUpload } from '@mdi/js'; -import Head from 'next/head'; -import React, { ReactElement, useEffect, useState } from 'react'; -import DatePicker from 'react-datepicker'; -import 'react-datepicker/dist/react-datepicker.css'; -import dayjs from 'dayjs'; - -import CardBox from '../../components/CardBox'; -import LayoutAuthenticated from '../../layouts/Authenticated'; -import SectionMain from '../../components/SectionMain'; -import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'; -import { getPageTitle } from '../../config'; - -import { Field, Form, Formik } from 'formik'; -import FormField from '../../components/FormField'; -import BaseDivider from '../../components/BaseDivider'; -import BaseButtons from '../../components/BaseButtons'; -import BaseButton from '../../components/BaseButton'; -import FormCheckRadio from '../../components/FormCheckRadio'; -import FormCheckRadioGroup from '../../components/FormCheckRadioGroup'; -import FormFilePicker from '../../components/FormFilePicker'; -import FormImagePicker from '../../components/FormImagePicker'; -import { SelectField } from '../../components/SelectField'; -import { SelectFieldMany } from '../../components/SelectFieldMany'; -import { SwitchField } from '../../components/SwitchField'; -import { RichTextField } from '../../components/RichTextField'; - -import { update, fetch } from '../../stores/likes/likesSlice'; -import { useAppDispatch, useAppSelector } from '../../stores/hooks'; -import { useRouter } from 'next/router'; -import { saveFile } from '../../helpers/fileSaver'; -import dataFormatter from '../../helpers/dataFormatter'; -import ImageField from '../../components/ImageField'; - -const EditLikes = () => { - const router = useRouter(); - const dispatch = useAppDispatch(); - const initVals = { - amount: '', - }; - const [initialValues, setInitialValues] = useState(initVals); - - const { likes } = useAppSelector((state) => state.likes); - - const { likesId } = router.query; - - useEffect(() => { - dispatch(fetch({ id: likesId })); - }, [likesId]); - - useEffect(() => { - if (typeof likes === 'object') { - setInitialValues(likes); - } - }, [likes]); - - useEffect(() => { - if (typeof likes === 'object') { - const newInitialVal = { ...initVals }; - - Object.keys(initVals).forEach((el) => (newInitialVal[el] = likes[el])); - - setInitialValues(newInitialVal); - } - }, [likes]); - - const handleSubmit = async (data) => { - await dispatch(update({ id: likesId, data })); - await router.push('/likes/likes-list'); - }; - - return ( - <> - - {getPageTitle('Edit likes')} - - - - {''} - - - handleSubmit(values)} - > -
- - - - - - - - - router.push('/likes/likes-list')} - /> - - -
-
-
- - ); -}; - -EditLikes.getLayout = function getLayout(page: ReactElement) { - return ( - - {page} - - ); -}; - -export default EditLikes; diff --git a/frontend/src/pages/likes/likes-edit.tsx b/frontend/src/pages/likes/likes-edit.tsx deleted file mode 100644 index e5626d0..0000000 --- a/frontend/src/pages/likes/likes-edit.tsx +++ /dev/null @@ -1,122 +0,0 @@ -import { mdiChartTimelineVariant, mdiUpload } from '@mdi/js'; -import Head from 'next/head'; -import React, { ReactElement, useEffect, useState } from 'react'; -import DatePicker from 'react-datepicker'; -import 'react-datepicker/dist/react-datepicker.css'; -import dayjs from 'dayjs'; - -import CardBox from '../../components/CardBox'; -import LayoutAuthenticated from '../../layouts/Authenticated'; -import SectionMain from '../../components/SectionMain'; -import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'; -import { getPageTitle } from '../../config'; - -import { Field, Form, Formik } from 'formik'; -import FormField from '../../components/FormField'; -import BaseDivider from '../../components/BaseDivider'; -import BaseButtons from '../../components/BaseButtons'; -import BaseButton from '../../components/BaseButton'; -import FormCheckRadio from '../../components/FormCheckRadio'; -import FormCheckRadioGroup from '../../components/FormCheckRadioGroup'; -import FormFilePicker from '../../components/FormFilePicker'; -import FormImagePicker from '../../components/FormImagePicker'; -import { SelectField } from '../../components/SelectField'; -import { SelectFieldMany } from '../../components/SelectFieldMany'; -import { SwitchField } from '../../components/SwitchField'; -import { RichTextField } from '../../components/RichTextField'; - -import { update, fetch } from '../../stores/likes/likesSlice'; -import { useAppDispatch, useAppSelector } from '../../stores/hooks'; -import { useRouter } from 'next/router'; -import { saveFile } from '../../helpers/fileSaver'; -import dataFormatter from '../../helpers/dataFormatter'; -import ImageField from '../../components/ImageField'; - -const EditLikesPage = () => { - const router = useRouter(); - const dispatch = useAppDispatch(); - const initVals = { - amount: '', - }; - const [initialValues, setInitialValues] = useState(initVals); - - const { likes } = useAppSelector((state) => state.likes); - - const { id } = router.query; - - useEffect(() => { - dispatch(fetch({ id: id })); - }, [id]); - - useEffect(() => { - if (typeof likes === 'object') { - setInitialValues(likes); - } - }, [likes]); - - useEffect(() => { - if (typeof likes === 'object') { - const newInitialVal = { ...initVals }; - Object.keys(initVals).forEach((el) => (newInitialVal[el] = likes[el])); - setInitialValues(newInitialVal); - } - }, [likes]); - - const handleSubmit = async (data) => { - await dispatch(update({ id: id, data })); - await router.push('/likes/likes-list'); - }; - - return ( - <> - - {getPageTitle('Edit likes')} - - - - {''} - - - handleSubmit(values)} - > -
- - - - - - - - - router.push('/likes/likes-list')} - /> - - -
-
-
- - ); -}; - -EditLikesPage.getLayout = function getLayout(page: ReactElement) { - return ( - - {page} - - ); -}; - -export default EditLikesPage; diff --git a/frontend/src/pages/likes/likes-list.tsx b/frontend/src/pages/likes/likes-list.tsx deleted file mode 100644 index 06fcca2..0000000 --- a/frontend/src/pages/likes/likes-list.tsx +++ /dev/null @@ -1,160 +0,0 @@ -import { mdiChartTimelineVariant } from '@mdi/js'; -import Head from 'next/head'; -import { uniqueId } from 'lodash'; -import React, { ReactElement, useState } from 'react'; -import CardBox from '../../components/CardBox'; -import LayoutAuthenticated from '../../layouts/Authenticated'; -import SectionMain from '../../components/SectionMain'; -import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'; -import { getPageTitle } from '../../config'; -import TableLikes from '../../components/Likes/TableLikes'; -import BaseButton from '../../components/BaseButton'; -import axios from 'axios'; -import Link from 'next/link'; -import { useAppDispatch, useAppSelector } from '../../stores/hooks'; -import CardBoxModal from '../../components/CardBoxModal'; -import DragDropFilePicker from '../../components/DragDropFilePicker'; -import { setRefetch, uploadCsv } from '../../stores/likes/likesSlice'; - -import { hasPermission } from '../../helpers/userPermissions'; - -const LikesTablesPage = () => { - const [filterItems, setFilterItems] = useState([]); - const [csvFile, setCsvFile] = useState(null); - const [isModalActive, setIsModalActive] = useState(false); - const [showTableView, setShowTableView] = useState(false); - - const { currentUser } = useAppSelector((state) => state.auth); - - const dispatch = useAppDispatch(); - - const [filters] = useState([{ label: 'Amount', title: 'amount' }]); - - const hasCreatePermission = - currentUser && hasPermission(currentUser, 'CREATE_LIKES'); - - const addFilter = () => { - const newItem = { - id: uniqueId(), - fields: { - filterValue: '', - filterValueFrom: '', - filterValueTo: '', - selectedField: '', - }, - }; - newItem.fields.selectedField = filters[0].title; - setFilterItems([...filterItems, newItem]); - }; - - const getLikesCSV = async () => { - const response = await axios({ - url: '/likes?filetype=csv', - method: 'GET', - responseType: 'blob', - }); - const type = response.headers['content-type']; - const blob = new Blob([response.data], { type: type }); - const link = document.createElement('a'); - link.href = window.URL.createObjectURL(blob); - link.download = 'likesCSV.csv'; - link.click(); - }; - - const onModalConfirm = async () => { - if (!csvFile) return; - await dispatch(uploadCsv(csvFile)); - dispatch(setRefetch(true)); - setCsvFile(null); - setIsModalActive(false); - }; - - const onModalCancel = () => { - setCsvFile(null); - setIsModalActive(false); - }; - - return ( - <> - - {getPageTitle('Likes')} - - - - {''} - - - {hasCreatePermission && ( - - )} - - - - - {hasCreatePermission && ( - setIsModalActive(true)} - /> - )} - -
-
-
-
- - - - -
- - - - - ); -}; - -LikesTablesPage.getLayout = function getLayout(page: ReactElement) { - return ( - {page} - ); -}; - -export default LikesTablesPage; diff --git a/frontend/src/pages/likes/likes-new.tsx b/frontend/src/pages/likes/likes-new.tsx deleted file mode 100644 index 21d974e..0000000 --- a/frontend/src/pages/likes/likes-new.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import { - mdiAccount, - mdiChartTimelineVariant, - mdiMail, - mdiUpload, -} from '@mdi/js'; -import Head from 'next/head'; -import React, { ReactElement } from 'react'; -import CardBox from '../../components/CardBox'; -import LayoutAuthenticated from '../../layouts/Authenticated'; -import SectionMain from '../../components/SectionMain'; -import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'; -import { getPageTitle } from '../../config'; - -import { Field, Form, Formik } from 'formik'; -import FormField from '../../components/FormField'; -import BaseDivider from '../../components/BaseDivider'; -import BaseButtons from '../../components/BaseButtons'; -import BaseButton from '../../components/BaseButton'; -import FormCheckRadio from '../../components/FormCheckRadio'; -import FormCheckRadioGroup from '../../components/FormCheckRadioGroup'; -import FormFilePicker from '../../components/FormFilePicker'; -import FormImagePicker from '../../components/FormImagePicker'; -import { SwitchField } from '../../components/SwitchField'; - -import { SelectField } from '../../components/SelectField'; -import { SelectFieldMany } from '../../components/SelectFieldMany'; -import { RichTextField } from '../../components/RichTextField'; - -import { create } from '../../stores/likes/likesSlice'; -import { useAppDispatch } from '../../stores/hooks'; -import { useRouter } from 'next/router'; -import moment from 'moment'; - -const initialValues = { - amount: '', -}; - -const LikesNew = () => { - const router = useRouter(); - const dispatch = useAppDispatch(); - - const handleSubmit = async (data) => { - await dispatch(create(data)); - await router.push('/likes/likes-list'); - }; - return ( - <> - - {getPageTitle('New Item')} - - - - {''} - - - handleSubmit(values)} - > -
- - - - - - - - - router.push('/likes/likes-list')} - /> - - -
-
-
- - ); -}; - -LikesNew.getLayout = function getLayout(page: ReactElement) { - return ( - - {page} - - ); -}; - -export default LikesNew; diff --git a/frontend/src/pages/likes/likes-table.tsx b/frontend/src/pages/likes/likes-table.tsx deleted file mode 100644 index c7869e6..0000000 --- a/frontend/src/pages/likes/likes-table.tsx +++ /dev/null @@ -1,159 +0,0 @@ -import { mdiChartTimelineVariant } from '@mdi/js'; -import Head from 'next/head'; -import { uniqueId } from 'lodash'; -import React, { ReactElement, useState } from 'react'; -import CardBox from '../../components/CardBox'; -import LayoutAuthenticated from '../../layouts/Authenticated'; -import SectionMain from '../../components/SectionMain'; -import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'; -import { getPageTitle } from '../../config'; -import TableLikes from '../../components/Likes/TableLikes'; -import BaseButton from '../../components/BaseButton'; -import axios from 'axios'; -import Link from 'next/link'; -import { useAppDispatch, useAppSelector } from '../../stores/hooks'; -import CardBoxModal from '../../components/CardBoxModal'; -import DragDropFilePicker from '../../components/DragDropFilePicker'; -import { setRefetch, uploadCsv } from '../../stores/likes/likesSlice'; - -import { hasPermission } from '../../helpers/userPermissions'; - -const LikesTablesPage = () => { - const [filterItems, setFilterItems] = useState([]); - const [csvFile, setCsvFile] = useState(null); - const [isModalActive, setIsModalActive] = useState(false); - const [showTableView, setShowTableView] = useState(false); - - const { currentUser } = useAppSelector((state) => state.auth); - - const dispatch = useAppDispatch(); - - const [filters] = useState([{ label: 'Amount', title: 'amount' }]); - - const hasCreatePermission = - currentUser && hasPermission(currentUser, 'CREATE_LIKES'); - - const addFilter = () => { - const newItem = { - id: uniqueId(), - fields: { - filterValue: '', - filterValueFrom: '', - filterValueTo: '', - selectedField: '', - }, - }; - newItem.fields.selectedField = filters[0].title; - setFilterItems([...filterItems, newItem]); - }; - - const getLikesCSV = async () => { - const response = await axios({ - url: '/likes?filetype=csv', - method: 'GET', - responseType: 'blob', - }); - const type = response.headers['content-type']; - const blob = new Blob([response.data], { type: type }); - const link = document.createElement('a'); - link.href = window.URL.createObjectURL(blob); - link.download = 'likesCSV.csv'; - link.click(); - }; - - const onModalConfirm = async () => { - if (!csvFile) return; - await dispatch(uploadCsv(csvFile)); - dispatch(setRefetch(true)); - setCsvFile(null); - setIsModalActive(false); - }; - - const onModalCancel = () => { - setCsvFile(null); - setIsModalActive(false); - }; - - return ( - <> - - {getPageTitle('Likes')} - - - - {''} - - - {hasCreatePermission && ( - - )} - - - - - {hasCreatePermission && ( - setIsModalActive(true)} - /> - )} - -
-
-
-
- - - -
- - - - - ); -}; - -LikesTablesPage.getLayout = function getLayout(page: ReactElement) { - return ( - {page} - ); -}; - -export default LikesTablesPage; diff --git a/frontend/src/pages/likes/likes-view.tsx b/frontend/src/pages/likes/likes-view.tsx deleted file mode 100644 index 9996c4f..0000000 --- a/frontend/src/pages/likes/likes-view.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import React, { ReactElement, useEffect } from 'react'; -import Head from 'next/head'; -import DatePicker from 'react-datepicker'; -import 'react-datepicker/dist/react-datepicker.css'; -import dayjs from 'dayjs'; -import { useAppDispatch, useAppSelector } from '../../stores/hooks'; -import { useRouter } from 'next/router'; -import { fetch } from '../../stores/likes/likesSlice'; -import { saveFile } from '../../helpers/fileSaver'; -import dataFormatter from '../../helpers/dataFormatter'; -import ImageField from '../../components/ImageField'; -import LayoutAuthenticated from '../../layouts/Authenticated'; -import { getPageTitle } from '../../config'; -import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'; -import SectionMain from '../../components/SectionMain'; -import CardBox from '../../components/CardBox'; -import BaseButton from '../../components/BaseButton'; -import BaseDivider from '../../components/BaseDivider'; -import { mdiChartTimelineVariant } from '@mdi/js'; -import { SwitchField } from '../../components/SwitchField'; -import FormField from '../../components/FormField'; - -const LikesView = () => { - const router = useRouter(); - const dispatch = useAppDispatch(); - const { likes } = useAppSelector((state) => state.likes); - - const { id } = router.query; - - function removeLastCharacter(str) { - console.log(str, `str`); - return str.slice(0, -1); - } - - useEffect(() => { - dispatch(fetch({ id })); - }, [dispatch, id]); - - return ( - <> - - {getPageTitle('View likes')} - - - - - - -
-

Amount

-

{likes?.amount}

-
- - - - router.push('/likes/likes-list')} - /> -
-
- - ); -}; - -LikesView.getLayout = function getLayout(page: ReactElement) { - return ( - {page} - ); -}; - -export default LikesView; diff --git a/frontend/src/pages/web_pages/about.tsx b/frontend/src/pages/web_pages/about.tsx index fcd775a..5b95af6 100644 --- a/frontend/src/pages/web_pages/about.tsx +++ b/frontend/src/pages/web_pages/about.tsx @@ -24,7 +24,7 @@ import TestimonialsSection from '../../components/WebPageComponents/Testimonials export default function WebSite() { const cardsStyle = useAppSelector((state) => state.style.cardsStyle); const bgColor = useAppSelector((state) => state.style.bgLayoutColor); - const projectName = 'save_schema_test'; + const projectName = 'saveschematest'; useEffect(() => { const darkElement = document.querySelector('body .dark'); @@ -122,10 +122,10 @@ export default function WebSite() { content={`Learn more about ${projectName}, our mission, values, and the innovative features that make us a leader in online education solutions.`} /> - +
- + ); } diff --git a/frontend/src/pages/web_pages/home.tsx b/frontend/src/pages/web_pages/home.tsx index 6a2bd83..cebc437 100644 --- a/frontend/src/pages/web_pages/home.tsx +++ b/frontend/src/pages/web_pages/home.tsx @@ -27,7 +27,7 @@ import ContactFormSection from '../../components/WebPageComponents/ContactFormCo export default function WebSite() { const cardsStyle = useAppSelector((state) => state.style.cardsStyle); const bgColor = useAppSelector((state) => state.style.bgLayoutColor); - const projectName = 'save_schema_test'; + const projectName = 'saveschematest'; useEffect(() => { const darkElement = document.querySelector('body .dark'); @@ -125,10 +125,10 @@ export default function WebSite() { content={`Explore our all-in-one platform for online education, offering course creation, student management, instructor profiles, and more. Enhance your learning experience today!`} /> - +
- + ); } diff --git a/frontend/src/pages/web_pages/services.tsx b/frontend/src/pages/web_pages/services.tsx index 524bb4d..1d41811 100644 --- a/frontend/src/pages/web_pages/services.tsx +++ b/frontend/src/pages/web_pages/services.tsx @@ -21,7 +21,7 @@ import TestimonialsSection from '../../components/WebPageComponents/Testimonials export default function WebSite() { const cardsStyle = useAppSelector((state) => state.style.cardsStyle); const bgColor = useAppSelector((state) => state.style.bgLayoutColor); - const projectName = 'save_schema_test'; + const projectName = 'saveschematest'; useEffect(() => { const darkElement = document.querySelector('body .dark'); @@ -119,10 +119,10 @@ export default function WebSite() { content={`Explore the comprehensive services offered by ${projectName}, designed to enhance online education and streamline management for educators and institutions.`} /> - +
- + ); } diff --git a/frontend/src/stores/likes/likesSlice.ts b/frontend/src/stores/likes/likesSlice.ts deleted file mode 100644 index aadbd82..0000000 --- a/frontend/src/stores/likes/likesSlice.ts +++ /dev/null @@ -1,236 +0,0 @@ -import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit'; -import axios from 'axios'; -import { - fulfilledNotify, - rejectNotify, - resetNotify, -} from '../../helpers/notifyStateHandler'; - -interface MainState { - likes: any; - loading: boolean; - count: number; - refetch: boolean; - rolesWidgets: any[]; - notify: { - showNotification: boolean; - textNotification: string; - typeNotification: string; - }; -} - -const initialState: MainState = { - likes: [], - loading: false, - count: 0, - refetch: false, - rolesWidgets: [], - notify: { - showNotification: false, - textNotification: '', - typeNotification: 'warn', - }, -}; - -export const fetch = createAsyncThunk('likes/fetch', async (data: any) => { - const { id, query } = data; - const result = await axios.get(`likes${query || (id ? `/${id}` : '')}`); - return id - ? result.data - : { rows: result.data.rows, count: result.data.count }; -}); - -export const deleteItemsByIds = createAsyncThunk( - 'likes/deleteByIds', - async (data: any, { rejectWithValue }) => { - try { - await axios.post('likes/deleteByIds', { data }); - } catch (error) { - if (!error.response) { - throw error; - } - - return rejectWithValue(error.response.data); - } - }, -); - -export const deleteItem = createAsyncThunk( - 'likes/deleteLikes', - async (id: string, { rejectWithValue }) => { - try { - await axios.delete(`likes/${id}`); - } catch (error) { - if (!error.response) { - throw error; - } - - return rejectWithValue(error.response.data); - } - }, -); - -export const create = createAsyncThunk( - 'likes/createLikes', - async (data: any, { rejectWithValue }) => { - try { - const result = await axios.post('likes', { data }); - return result.data; - } catch (error) { - if (!error.response) { - throw error; - } - - return rejectWithValue(error.response.data); - } - }, -); - -export const uploadCsv = createAsyncThunk( - 'likes/uploadCsv', - async (file: File, { rejectWithValue }) => { - try { - const data = new FormData(); - data.append('file', file); - data.append('filename', file.name); - - const result = await axios.post('likes/bulk-import', data, { - headers: { - 'Content-Type': 'multipart/form-data', - }, - }); - - return result.data; - } catch (error) { - if (!error.response) { - throw error; - } - - return rejectWithValue(error.response.data); - } - }, -); - -export const update = createAsyncThunk( - 'likes/updateLikes', - async (payload: any, { rejectWithValue }) => { - try { - const result = await axios.put(`likes/${payload.id}`, { - id: payload.id, - data: payload.data, - }); - return result.data; - } catch (error) { - if (!error.response) { - throw error; - } - - return rejectWithValue(error.response.data); - } - }, -); - -export const likesSlice = createSlice({ - name: 'likes', - initialState, - reducers: { - setRefetch: (state, action: PayloadAction) => { - state.refetch = action.payload; - }, - }, - extraReducers: (builder) => { - builder.addCase(fetch.pending, (state) => { - state.loading = true; - resetNotify(state); - }); - builder.addCase(fetch.rejected, (state, action) => { - state.loading = false; - rejectNotify(state, action); - }); - - builder.addCase(fetch.fulfilled, (state, action) => { - if (action.payload.rows && action.payload.count >= 0) { - state.likes = action.payload.rows; - state.count = action.payload.count; - } else { - state.likes = action.payload; - } - state.loading = false; - }); - - builder.addCase(deleteItemsByIds.pending, (state) => { - state.loading = true; - resetNotify(state); - }); - - builder.addCase(deleteItemsByIds.fulfilled, (state) => { - state.loading = false; - fulfilledNotify(state, 'Likes has been deleted'); - }); - - builder.addCase(deleteItemsByIds.rejected, (state, action) => { - state.loading = false; - rejectNotify(state, action); - }); - - builder.addCase(deleteItem.pending, (state) => { - state.loading = true; - resetNotify(state); - }); - - builder.addCase(deleteItem.fulfilled, (state) => { - state.loading = false; - fulfilledNotify(state, `${'Likes'.slice(0, -1)} has been deleted`); - }); - - builder.addCase(deleteItem.rejected, (state, action) => { - state.loading = false; - rejectNotify(state, action); - }); - - builder.addCase(create.pending, (state) => { - state.loading = true; - resetNotify(state); - }); - builder.addCase(create.rejected, (state, action) => { - state.loading = false; - rejectNotify(state, action); - }); - - builder.addCase(create.fulfilled, (state) => { - state.loading = false; - fulfilledNotify(state, `${'Likes'.slice(0, -1)} has been created`); - }); - - builder.addCase(update.pending, (state) => { - state.loading = true; - resetNotify(state); - }); - builder.addCase(update.fulfilled, (state) => { - state.loading = false; - fulfilledNotify(state, `${'Likes'.slice(0, -1)} has been updated`); - }); - builder.addCase(update.rejected, (state, action) => { - state.loading = false; - rejectNotify(state, action); - }); - - builder.addCase(uploadCsv.pending, (state) => { - state.loading = true; - resetNotify(state); - }); - builder.addCase(uploadCsv.fulfilled, (state) => { - state.loading = false; - fulfilledNotify(state, 'Likes has been uploaded'); - }); - builder.addCase(uploadCsv.rejected, (state, action) => { - state.loading = false; - rejectNotify(state, action); - }); - }, -}); - -// Action creators are generated for each case reducer function -export const { setRefetch } = likesSlice.actions; - -export default likesSlice.reducer; diff --git a/frontend/src/stores/store.ts b/frontend/src/stores/store.ts index 3a71946..aaf78cc 100644 --- a/frontend/src/stores/store.ts +++ b/frontend/src/stores/store.ts @@ -13,7 +13,6 @@ import instructorsSlice from './instructors/instructorsSlice'; import studentsSlice from './students/studentsSlice'; import rolesSlice from './roles/rolesSlice'; import permissionsSlice from './permissions/permissionsSlice'; -import likesSlice from './likes/likesSlice'; export const store = configureStore({ reducer: { @@ -31,7 +30,6 @@ export const store = configureStore({ students: studentsSlice, roles: rolesSlice, permissions: permissionsSlice, - likes: likesSlice, }, });