summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHombreLaser <sebastian-440@live.com>2023-05-12 23:01:55 -0600
committerHombreLaser <sebastian-440@live.com>2023-05-12 23:01:55 -0600
commitcbebedd51e1b4a2f709341b792dd073bac83f15d (patch)
tree832f7e56e430e5863f4381c78c49119339076436 /src
parent385606ee05a8ceb9073169639eb1a311f81cac10 (diff)
Añadido formulario de edición de cuenta
Diffstat (limited to 'src')
-rw-r--r--src/clients/actions.ts18
-rw-r--r--src/clients/api_client.ts30
-rw-r--r--src/clients/loaders.ts1
-rw-r--r--src/lib/form_utils.ts10
-rw-r--r--src/lib/token.ts27
-rw-r--r--src/main.tsx8
-rw-r--r--src/routes/account/account.tsx2
-rw-r--r--src/routes/account/edit.tsx40
8 files changed, 122 insertions, 14 deletions
diff --git a/src/clients/actions.ts b/src/clients/actions.ts
new file mode 100644
index 0000000..36935cb
--- /dev/null
+++ b/src/clients/actions.ts
@@ -0,0 +1,18 @@
+import { redirect } from "react-router-dom";
+import { ApiClient } from "./api_client";
+import { deleteEmptyFields } from "../lib/form_utils";
+
+export async function editAccount({ request }) {
+ const client = new ApiClient();
+ let form_data = await request.formData();
+ form_data = deleteEmptyFields(form_data);
+ const response = await client.put("/account", form_data);
+
+ if(response.status == 401)
+ return redirect("/products");
+
+ client.token.set(response.data.token);
+ client.token.setRefresh(response.data.refresh);
+
+ return redirect("/account");
+} \ No newline at end of file
diff --git a/src/clients/api_client.ts b/src/clients/api_client.ts
index fc2d361..93d713a 100644
--- a/src/clients/api_client.ts
+++ b/src/clients/api_client.ts
@@ -3,27 +3,19 @@ import Token from "../lib/token";
export class ApiClient {
readonly url = "http://localhost:3000/api";
- token = new Token();
+ public readonly token = new Token();
async authenticatedGet(path: string) {
const request_url = `${ this.url }${ path }`;
let request: any;
- let options = {
- headers: {
- Authorization: this.token.get()
- }
- };
+ let options = this.authorizationHeaders();
request = await this.makeGetRequest(request_url, options);
if(request.response) {
// Let's try with a refreshed token.
this.token.refresh()
- options = {
- headers: {
- Authorization: this.token.getRefresh()
- }
- };
+ options = this.authorizationHeaders();
request = await this.makeGetRequest(request_url, options);
}
@@ -44,6 +36,14 @@ export class ApiClient {
return response;
}
+ async put(path: string, data: FormData) {
+ const request_url = `${ this.url }${ path }`;
+ const options = this.authorizationHeaders();
+ const response = await axios.put(request_url, data, options);
+
+ return response;
+ }
+
async getProduct(id: string) {
const request_url = `${ this.url }/products/${ id }`;
const [product_response, product_reviews] = await Promise.all([
@@ -63,4 +63,12 @@ export class ApiClient {
return error;
}
}
+
+ private authorizationHeaders() {
+ return {
+ headers: {
+ Authorization: this.token.get()
+ }
+ };
+ }
} \ No newline at end of file
diff --git a/src/clients/loaders.ts b/src/clients/loaders.ts
index d9972d5..8d0f06f 100644
--- a/src/clients/loaders.ts
+++ b/src/clients/loaders.ts
@@ -1,5 +1,4 @@
import { redirect } from "react-router-dom";
-import Token from "../lib/token";
import { ApiClient } from "./api_client";
export async function loader({ request }) {
diff --git a/src/lib/form_utils.ts b/src/lib/form_utils.ts
new file mode 100644
index 0000000..a4e7bff
--- /dev/null
+++ b/src/lib/form_utils.ts
@@ -0,0 +1,10 @@
+export function deleteEmptyFields(form: FormData) {
+ const trimmed_form = form;
+
+ for(const key of trimmed_form) {
+ if(trimmed_form.get(key[0]) == '')
+ trimmed_form.delete(key[0]);
+ }
+
+ return trimmed_form;
+} \ No newline at end of file
diff --git a/src/lib/token.ts b/src/lib/token.ts
index 05de87e..93ec0cf 100644
--- a/src/lib/token.ts
+++ b/src/lib/token.ts
@@ -1,4 +1,4 @@
-import { ApiClient } from "../clients/api_client";
+import jwt_decode from "jwt-decode";
import axios from "axios";
export default class Token {
@@ -42,4 +42,29 @@ export default class Token {
this.logout();
}
}
+
+ getEmail() {
+ return this.decode()?.data;
+ }
+
+ getRole() {
+ return this.decode()?.aud;
+ }
+
+ getJTI() {
+ return this.decode()?.jti;
+ }
+
+ getExpirationDate() {
+ return this.decode()?.exp;
+ }
+
+ private decode(): { data: string; aud: string; jti: string; exp: number; } | null {
+ const token = this.get();
+
+ if(token != null)
+ return jwt_decode(token);
+
+ return null;
+ }
} \ No newline at end of file
diff --git a/src/main.tsx b/src/main.tsx
index a3eb1b2..cd65146 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -5,6 +5,8 @@ import Products from "./routes/products/products";
import Product from "./routes/products/product";
import Companies from "./routes/companies/companies";
import Account from "./routes/account/account";
+import { EditAccount } from './routes/account/edit';
+import { editAccount } from './clients/actions';
import Layout from "./components/layout";
import { accountLoader, loader, productLoader } from "./clients/loaders";
import './index.css';
@@ -31,6 +33,12 @@ const routes = [
element: <Account/>
},
{
+ path: "/account/edit",
+ element: <EditAccount/>,
+ loader: accountLoader,
+ action: editAccount
+ },
+ {
path: '/',
element: <Navigate to='/products'/>
}
diff --git a/src/routes/account/account.tsx b/src/routes/account/account.tsx
index 8458285..8a04427 100644
--- a/src/routes/account/account.tsx
+++ b/src/routes/account/account.tsx
@@ -29,7 +29,7 @@ export default function Account() {
<span className="mx-1 field_name">Correo electrónico:</span> {email}
</div>
<div>
- <a type="button" className="button text-white hover:bg-blue-300 hover:text-gray focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 mr-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800" href="#">
+ <a type="button" className="button text-white hover:bg-blue-300 hover:text-gray focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 mr-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800" href="/account/edit">
Editar
</a>
</div>
diff --git a/src/routes/account/edit.tsx b/src/routes/account/edit.tsx
new file mode 100644
index 0000000..c2dfcb5
--- /dev/null
+++ b/src/routes/account/edit.tsx
@@ -0,0 +1,40 @@
+import MainContentLayout from "../../components/main_content_layout";
+import Token from "../../lib/token";
+import { Form, useLoaderData } from "react-router-dom";
+import "../../components/stylesheets/shared.css";
+
+export function EditAccount() {
+ const account = useLoaderData()[0].data.data.attributes;
+ const token = new Token();
+
+ return(
+ <>
+ <MainContentLayout>
+ <div className="w-4/5 my-6">
+ <h1 className="my-6 text-3xl">
+ Editar cuenta
+ </h1>
+ <Form method="post" id="account-form">
+ <div className="mb-6">
+ <label className="block mb-2 text-lg text-gray-900 dark:text-white">Correo electrónico</label>
+ <input type="email" id="email" name="email" className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder={account.email}/>
+ </div>
+ <div className="mb-6">
+ <label className="block mb-2 text-lg text-gray-900 dark:text-white">Nombre</label>
+ <input type="text" id="first_name" name="first_name" className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder={account.first_name}/>
+ </div>
+ <div className="mb-6">
+ <label className="block mb-2 text-lg text-gray-900 dark:text-white">Apellido</label>
+ <input type="text" id="last_name" name="last_name" className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder={account.last_name}/>
+ </div>
+ <div className="mb-6">
+ <label className="block mb-2 text-lg text-gray-900 dark:text-white">Contraseña</label>
+ <input type="password" id="password" name="password" className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"/>
+ </div>
+ <button type="submit" className="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Enviar</button>
+ </Form>
+ </div>
+ </MainContentLayout>
+ </>
+ );
+} \ No newline at end of file