diff --git a/backend/base/settings.py b/backend/base/settings.py index f9e401c..9c63326 100644 --- a/backend/base/settings.py +++ b/backend/base/settings.py @@ -28,6 +28,10 @@ ALLOWED_HOSTS: list[str] = ["*", "http://localhost", "localhost"] +CSRF_TRUSTED_ORIGINS = [ + 'http://localhost', 'http://localhost:80', 'http://localhost:4200', 'http://localhost:6969' +] + INSTALLED_APPS = [ # 'daphne', "django.contrib.admin", @@ -47,7 +51,7 @@ "django.middleware.security.SecurityMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.common.CommonMiddleware", - # "django.middleware.csrf.CsrfViewMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", @@ -55,10 +59,11 @@ ] CORS_ORIGIN_ALLOW_ALL = True -# CORS_ORIGIN_WHITELIST = ("http://localhost:5173",) +CORS_ALLOW_ALL_ORIGINS = True ASGI_APPLICATION = "api.routing.application" -CHANNEL_LAYERS = {"default": {"BACKEND": "channels.layers.InMemoryChannelLayer"}} +CHANNEL_LAYERS = {"default": { + "BACKEND": "channels.layers.InMemoryChannelLayer"}} MESSAGE_STORAGE = "django.contrib.messages.storage.cookie.CookieStorage" diff --git a/frontend/index.html b/frontend/index.html index 4a61806..35d9324 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1,16 +1,16 @@ - - - - - - - CSLC Tutoring Portal - - -
- - - + + + + + CSLC Tutoring Portal + + + +
+ + + + \ No newline at end of file diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 2c5d357..5a77fa0 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -42,6 +42,7 @@ "@radix-ui/themes": "^1.1.2", "@tailwindcss/forms": "^0.5.6", "@tanstack/react-query": "^5.0.5", + "@tanstack/react-query-devtools": "^5.8.4", "@tanstack/react-table": "^8.10.7", "@types/react-router-dom": "^5.3.3", "axios": "^1.5.1", @@ -54,7 +55,6 @@ "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.3", - "i": "^0.3.7", "lucide-react": "^0.277.0", "npm": "^10.2.3", "postcss": "^8.4.29", @@ -6258,20 +6258,29 @@ } }, "node_modules/@tanstack/query-core": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.0.5.tgz", - "integrity": "sha512-MThCETMkHDHTnFZHp71L+SqTtD5d6XHftFCVR1xRJdWM3qGrlQ2VCXaj0SKVcyJej2e1Opa2c7iknu1llxCDNQ==", + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.8.3.tgz", + "integrity": "sha512-SWFMFtcHfttLYif6pevnnMYnBvxKf3C+MHMH7bevyYfpXpTMsLB9O6nNGBdWSoPwnZRXFNyNeVZOw25Wmdasow==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/query-devtools": { + "version": "5.8.4", + "resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.8.4.tgz", + "integrity": "sha512-F1dRbITNt9tMUoM9WCH8WQ2c54116hv52m/PKK8ZiN/pO2wGVzTZtKuLanF8pFpwmNchjIixcMw/a57HY5ivcw==", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" } }, "node_modules/@tanstack/react-query": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.0.5.tgz", - "integrity": "sha512-ZG0Q4HZ0iuI8mWiZ2/MdVYPHbrmAVhMn7+gLOkxJh6zLIgCL4luSZlohzN5Xt4MjxfxxWioO1nemwpudaTsmQg==", + "version": "5.8.4", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.8.4.tgz", + "integrity": "sha512-CD+AkXzg8J72JrE6ocmuBEJfGzEzu/bzkD6sFXFDDB5yji9N20JofXZlN6n0+CaPJuIi+e4YLCbGsyPFKkfNQA==", "dependencies": { - "@tanstack/query-core": "5.0.5" + "@tanstack/query-core": "5.8.3" }, "funding": { "type": "github", @@ -6291,6 +6300,23 @@ } } }, + "node_modules/@tanstack/react-query-devtools": { + "version": "5.8.4", + "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.8.4.tgz", + "integrity": "sha512-mffs51FJqXU/5rwhbwv393DccL6et7uK2pRLwOcmMrWbPyW8vpxr9oidaghHX4cdVeP/7u5owW9yMpBhBAJfcQ==", + "dependencies": { + "@tanstack/query-devtools": "5.8.4" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@tanstack/react-query": "^5.8.4", + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, "node_modules/@tanstack/react-table": { "version": "8.10.7", "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.10.7.tgz", @@ -10197,14 +10223,6 @@ "node": ">=10.17.0" } }, - "node_modules/i": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/i/-/i-0.3.7.tgz", - "integrity": "sha512-FYz4wlXgkQwIPqhzC5TdNMLSE5+GS1IIDJZY/1ZiEPCT2S3COUVZeT5OW4BmW4r5LHLQuOosSwsvnroG9GR59Q==", - "engines": { - "node": ">=0.4" - } - }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index 86aac69..fed0e9f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -44,6 +44,7 @@ "@radix-ui/themes": "^1.1.2", "@tailwindcss/forms": "^0.5.6", "@tanstack/react-query": "^5.0.5", + "@tanstack/react-query-devtools": "^5.8.4", "@tanstack/react-table": "^8.10.7", "@types/react-router-dom": "^5.3.3", "axios": "^1.5.1", diff --git a/frontend/src/API/professors/useMutateProfessor.ts b/frontend/src/API/professors/useMutateProfessor.ts new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/API/tickets/ticketRequests.ts b/frontend/src/API/tickets/ticketRequests.ts new file mode 100644 index 0000000..b56d7d7 --- /dev/null +++ b/frontend/src/API/tickets/ticketRequests.ts @@ -0,0 +1,23 @@ +import axios from "axios" + +export function createTicket(data: any) { + function getCookie(name) { + const value = `; ${document.cookie}`; + const parts = value.split(`; ${name}=`); + if (parts.length === 2) return parts.pop().split(';').shift(); + } + const csrftoken = getCookie('csrftoken'); + return axios.post("/api/tickets/", { + name: data.student_name, + description: data.body, + professor: data.professor, + course: data.section, + issue: data.issue, + }, + { + headers: { + 'X-CSRFToken': csrftoken + } + }) + .then(res => res.data); +} \ No newline at end of file diff --git a/frontend/src/components/forms/TicketForm.tsx b/frontend/src/components/forms/TicketForm.tsx index 8941ef8..3e499fc 100644 --- a/frontend/src/components/forms/TicketForm.tsx +++ b/frontend/src/components/forms/TicketForm.tsx @@ -31,10 +31,10 @@ import useFetchProfessor from "@/API/professors/useFetchProfessor"; import useFetchCourse from "@/API/courses/useFetchCourse"; import useFetchIssue from "@/API/issues/useFetchIssue"; import { ScrollArea } from "../ui/scroll-area"; -import axios from "axios"; import LoadingSelect from "../loading/loading_select"; import { useMutation } from "@tanstack/react-query"; import { useToast } from "@/components/ui/use-toast"; +import { createTicket } from "@/API/tickets/ticketRequests"; // import useFetchSection from "@/API/sections/useFetchSection"; const max_ticket_length = 500; @@ -94,19 +94,11 @@ export default function TicketForm() { const { toast } = useToast(); const mutation = useMutation({ - mutationFn: (data) => { - return axios.post("http://localhost:6969/api/tickets/", { - name: data.student_name, - description: data.body, - professor: data.professor, - course: data.section, - issue: data.issue, - }); - }, + mutationFn: createTicket, }); - async function onSubmit(data: z.infer) { - await mutation.mutateAsync(data); + function onSubmit(data: z.infer) { + mutation.mutate(data); toast({ title: "Scheduled: Catch up", description: "Friday, February 10, 2023 at 5:57 PM", @@ -191,14 +183,14 @@ export default function TicketForm() { className={cn( "w-full md:w-[35vw] lg:w-[30vw] xl:w-[40vw] justify-between", !field.value && - "text-muted-foreground font-normal", + "text-muted-foreground font-normal", )} > {field.value ? professors?.data.find( - (professor: any) => - professor.professor_id === field.value, - )?.full_name + (professor: any) => + professor.professor_id === field.value, + )?.full_name : "select a professor"} @@ -272,13 +264,13 @@ export default function TicketForm() { className={cn( "w-full md:w-[35vw] lg:w-[30vw] xl:w-[40vw] justify-between", !field.value && - "text-muted-foreground font-normal", + "text-muted-foreground font-normal", )} > {field.value ? courses?.data.find( - (course: any) => course.id === field.value, - )?.course_code + (course: any) => course.id === field.value, + )?.course_code : "select a course"} {field.value ? issues?.data.find( - (issue: any) => - issue.issue_id === field.value, - )?.problem_type + (issue: any) => + issue.issue_id === field.value, + )?.problem_type : "select an issue"} )} /> - + diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index e5066a5..413928a 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -30,6 +30,7 @@ import ForEthan from "./views/ethan.tsx"; import { PublicClientApplication } from "@azure/msal-browser"; import { MsalProvider } from "@azure/msal-react"; import { msalConfig } from "./authConfig.ts"; +import { ReactQueryDevtools } from '@tanstack/react-query-devtools' const queryClient = new QueryClient(); @@ -126,6 +127,7 @@ ReactDOM.createRoot(document.getElementById("root")!).render( + diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js index e26b9d4..af2627d 100644 --- a/frontend/tailwind.config.js +++ b/frontend/tailwind.config.js @@ -7,7 +7,6 @@ module.exports = { "./components/**/*.{ts,tsx}", "./app/**/*.{ts,tsx}", "./src/**/*.{ts,tsx}", - "node_modules/preline/dist/*.js", ], theme: { container: { diff --git a/nginx/nginx.conf b/nginx/nginx.conf index a28b9e1..838ab5e 100644 --- a/nginx/nginx.conf +++ b/nginx/nginx.conf @@ -20,6 +20,9 @@ server { # All frontend requests location / { + proxy_set_header 'Access-Control-Allow-Credentials' 'true'; + # proxy_set_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,X-CSRFToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; + proxy_set_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH'; proxy_pass http://frontend:4200; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;