From bc3afa860471fcec12647016eb4223b784fc7a97 Mon Sep 17 00:00:00 2001 From: keannu125 Date: Sat, 25 Mar 2023 12:33:27 +0800 Subject: [PATCH] Polished apis and fixed some missing files --- src/Features/Redux/Store/Api.tsx | 134 ++++++++++++++++++++++ src/Features/Redux/Store/LoginSlice.tsx | 21 ++++ src/Features/Redux/Store/ViewEditNote.tsx | 116 +++++++++++++++++++ 3 files changed, 271 insertions(+) create mode 100644 src/Features/Redux/Store/Api.tsx create mode 100644 src/Features/Redux/Store/LoginSlice.tsx create mode 100644 src/Features/Redux/Store/ViewEditNote.tsx diff --git a/src/Features/Redux/Store/Api.tsx b/src/Features/Redux/Store/Api.tsx new file mode 100644 index 0000000..d93144c --- /dev/null +++ b/src/Features/Redux/Store/Api.tsx @@ -0,0 +1,134 @@ +import axios from "axios"; +import { + ActivationParams, + UpdateNoteParams, + AddNoteParams, + LoginParams, + RegistrationParams, +} from "../../Interfaces/Interfaces"; + +// Note APIs + +const instance = axios.create({ + baseURL: "https://keannu126.pythonanywhere.com", +}); + +export function GetNotes() { + const token = JSON.parse(localStorage.getItem("token") || "{}"); + return instance + .get("/api/v1/notes/", { + headers: { + Authorization: "Token " + token, + }, + }) + .then((response) => { + return response.data; + }); +} + +export function GetNote(id: number) { + const token = JSON.parse(localStorage.getItem("token") || "{}"); + return instance + .get("/api/v1/notes/" + id + "/", { + headers: { + Authorization: "Token " + token, + }, + }) + .then((response) => { + return response.data; + }); +} + +export function UpdateNote(note: UpdateNoteParams) { + const token = JSON.parse(localStorage.getItem("token") || "{}"); + return instance + .patch("/api/v1/notes/" + note.id + "/", note, { + headers: { + Authorization: "Token " + token, + }, + }) + .then((response) => { + return response.data; + }) + .catch((error) => { + return error; + }); +} + +export function AddNote(note: AddNoteParams) { + const token = JSON.parse(localStorage.getItem("token") || "{}"); + return instance + .post("/api/v1/notes/", note, { + headers: { + Authorization: "Token " + token, + }, + }) + .then((response) => { + return response.data; + }) + .catch((error) => { + return error; + }); +} + +export function DeleteNote(id: number) { + const token = JSON.parse(localStorage.getItem("token") || "{}"); + return instance + .delete("/api/v1/notes/" + id + "/", { + headers: { + Authorization: "Token " + token, + }, + }) + .catch((error) => { + return error; + }); +} + +// User APIs + +export function UserRegister(register: RegistrationParams) { + return instance + .post("/api/v1/accounts/users/", register) + .then(async (response) => { + return true; + }) + .catch((error) => { + return false; + }); +} + +export function UserLogin(user: LoginParams) { + return instance + .post("/api/v1/accounts/token/login/", user) + .then(async (response) => { + localStorage.setItem("token", JSON.stringify(response.data.auth_token)); + return true; + }) + .catch((error) => { + return false; + }); +} + +export function UserInfo() { + const token = JSON.parse(localStorage.getItem("token") || "{}"); + return instance + .get("/api/v1/accounts/users/me/", { + headers: { + Authorization: "Token " + token, + }, + }) + .then((response) => { + return response.data; + }); +} + +export function UserActivate(activation: ActivationParams) { + return instance + .post("/api/v1/accounts/users/activation/", activation) + .then(async (response) => { + return true; + }) + .catch((error) => { + return false; + }); +} diff --git a/src/Features/Redux/Store/LoginSlice.tsx b/src/Features/Redux/Store/LoginSlice.tsx new file mode 100644 index 0000000..5802c33 --- /dev/null +++ b/src/Features/Redux/Store/LoginSlice.tsx @@ -0,0 +1,21 @@ +import { createSlice } from "@reduxjs/toolkit"; + +export const LoginSlice = createSlice({ + name: "Login", + initialState: { + value: false, + }, + reducers: { + SetLoggedIn: (state) => { + state.value = !state.value; + }, + SetLoggedOut: (state) => { + state.value = !state.value; + }, + }, +}); + +// Action creators are generated for each case reducer function +export const { SetLoggedIn, SetLoggedOut } = LoginSlice.actions; + +export default LoginSlice.reducer; diff --git a/src/Features/Redux/Store/ViewEditNote.tsx b/src/Features/Redux/Store/ViewEditNote.tsx new file mode 100644 index 0000000..3226e69 --- /dev/null +++ b/src/Features/Redux/Store/ViewEditNote.tsx @@ -0,0 +1,116 @@ +import styles from "../../styles"; +import { Button } from "@mui/material"; +import { useNavigate, useParams } from "react-router-dom"; +import { useEffect, useState } from "react"; +import Header from "../../Components/Header/Header"; +import { GetNote, UpdateNote } from "../../Components/Api/Api"; +import { useMutation, useQuery, useQueryClient } from "react-query"; + +export interface input { + e: React.ChangeEvent; +} +export default function ViewNote() { + const navigate = useNavigate(); + const { id } = useParams(); + const queryClient = useQueryClient(); + const mutation = useMutation({ + mutationFn: UpdateNote, + onSuccess: () => { + queryClient.invalidateQueries("notes"); + }, + }); + const [note, setNote] = useState({ + title: "", + content: "", + }); + async function retrieve() { + let a = await GetNote(Number(id)); + setNote(a); + return a; + } + const { data, isLoading, error } = useQuery("note", retrieve, { + retry: 0, + }); + useEffect(() => { + setNote(data); + }, [data]); + if (error) { + return ( +
+
+
+

Error retrieving specific note

+
+
+ ); + } + if (isLoading) { + return ( +
+
+

Loading Note...

+
+
+ ); + } + if (data) { + return ( +
+
+

Edit Note

+
+
+
+

Title: 

+ { + setNote({ ...note, title: e.target.value }); + }} + maxLength={20} + /> +
+
+