diff --git a/.vscode/launch.json b/.vscode/launch.json index f7faaa1..799386b 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,6 +1,14 @@ { "version": "0.2.0", "configurations": [ + { + "command": "yarn dev", + "name": "Next.js", + "request": "launch", + "cwd": "${workspaceFolder}/Next", + "type": "node-terminal" + }, + { "name": "TestAppRuna", "type": "coreclr", diff --git a/Next/APIClient.ts b/Next/APIClient.ts new file mode 100644 index 0000000..3941fa7 --- /dev/null +++ b/Next/APIClient.ts @@ -0,0 +1,716 @@ +/* tslint:disable */ +/* eslint-disable */ +//---------------------- +// +// Generated using the NSwag toolchain v13.10.8.0 (NJsonSchema v10.3.11.0 (Newtonsoft.Json v11.0.0.0)) (http://NSwag.org) +// +//---------------------- +// ReSharper disable InconsistentNaming + +export class CartClient { + private http: { fetch(url: RequestInfo, init?: RequestInit): Promise }; + private baseUrl: string; + protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined; + + constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise }) { + this.http = http ? http : window; + this.baseUrl = baseUrl !== undefined && baseUrl !== null ? baseUrl : "http://localhost:5000"; + } + + get(): Promise { + let url_ = this.baseUrl + "/api/Cart"; + url_ = url_.replace(/[?&]$/, ""); + + let options_ = { + method: "GET", + headers: { + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processGet(_response); + }); + } + + protected processGet(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + return result200; + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } + + post(model: CartCreateUpdateModel): Promise { + let url_ = this.baseUrl + "/api/Cart"; + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(model); + + let options_ = { + body: content_, + method: "POST", + headers: { + "Content-Type": "application/json", + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processPost(_response); + }); + } + + protected processPost(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + return result200; + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } + + getFromCustomer(customerId: string): Promise { + let url_ = this.baseUrl + "/api/Cart/{customerId}"; + if (customerId === undefined || customerId === null) + throw new Error("The parameter 'customerId' must be defined."); + url_ = url_.replace("{customerId}", encodeURIComponent("" + customerId)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ = { + method: "GET", + headers: { + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processGetFromCustomer(_response); + }); + } + + protected processGetFromCustomer(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + return result200; + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } + + delete(model: CartDeleteModel): Promise { + let url_ = this.baseUrl + "/api/Cart/delete"; + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(model); + + let options_ = { + body: content_, + method: "POST", + headers: { + "Content-Type": "application/json", + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processDelete(_response); + }); + } + + protected processDelete(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + return result200; + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } +} + +export class CustomerClient { + private http: { fetch(url: RequestInfo, init?: RequestInit): Promise }; + private baseUrl: string; + protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined; + + constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise }) { + this.http = http ? http : window; + this.baseUrl = baseUrl !== undefined && baseUrl !== null ? baseUrl : "http://localhost:5000"; + } + + getAll(): Promise { + let url_ = this.baseUrl + "/api/Customer"; + url_ = url_.replace(/[?&]$/, ""); + + let options_ = { + method: "GET", + headers: { + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processGetAll(_response); + }); + } + + protected processGetAll(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + return result200; + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } + + post(model: CustomerCreateUpdateModel): Promise { + let url_ = this.baseUrl + "/api/Customer"; + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(model); + + let options_ = { + body: content_, + method: "POST", + headers: { + "Content-Type": "application/json", + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processPost(_response); + }); + } + + protected processPost(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + return result200; + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } + + get(id: string): Promise { + let url_ = this.baseUrl + "/api/Customer/{id}"; + if (id === undefined || id === null) + throw new Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ = { + method: "GET", + headers: { + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processGet(_response); + }); + } + + protected processGet(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + return result200; + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } + + put(id: string, model: CustomerCreateUpdateModel): Promise { + let url_ = this.baseUrl + "/api/Customer/{id}"; + if (id === undefined || id === null) + throw new Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(model); + + let options_ = { + body: content_, + method: "PUT", + headers: { + "Content-Type": "application/json", + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processPut(_response); + }); + } + + protected processPut(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + return result200; + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } + + delete(id: string): Promise { + let url_ = this.baseUrl + "/api/Customer/{id}"; + if (id === undefined || id === null) + throw new Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ = { + method: "DELETE", + headers: { + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processDelete(_response); + }); + } + + protected processDelete(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + return result200; + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } +} + +export class MathClient { + private http: { fetch(url: RequestInfo, init?: RequestInit): Promise }; + private baseUrl: string; + protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined; + + constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise }) { + this.http = http ? http : window; + this.baseUrl = baseUrl !== undefined && baseUrl !== null ? baseUrl : "http://localhost:5000"; + } + + get(): Promise { + let url_ = this.baseUrl + "/api/Math"; + url_ = url_.replace(/[?&]$/, ""); + + let options_ = { + method: "GET", + headers: { + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processGet(_response); + }); + } + + protected processGet(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + return result200; + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } +} + +export class ProductClient { + private http: { fetch(url: RequestInfo, init?: RequestInit): Promise }; + private baseUrl: string; + protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined; + + constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise }) { + this.http = http ? http : window; + this.baseUrl = baseUrl !== undefined && baseUrl !== null ? baseUrl : "http://localhost:5000"; + } + + getAll(): Promise { + let url_ = this.baseUrl + "/api/Product"; + url_ = url_.replace(/[?&]$/, ""); + + let options_ = { + method: "GET", + headers: { + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processGetAll(_response); + }); + } + + protected processGetAll(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + return result200; + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } + + post(model: ProductCreateUpdateModel): Promise { + let url_ = this.baseUrl + "/api/Product"; + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(model); + + let options_ = { + body: content_, + method: "POST", + headers: { + "Content-Type": "application/json", + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processPost(_response); + }); + } + + protected processPost(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + return result200; + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } + + get(id: string): Promise { + let url_ = this.baseUrl + "/api/Product/{id}"; + if (id === undefined || id === null) + throw new Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ = { + method: "GET", + headers: { + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processGet(_response); + }); + } + + protected processGet(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + return result200; + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } + + put(id: string, model: ProductCreateUpdateModel): Promise { + let url_ = this.baseUrl + "/api/Product/{id}"; + if (id === undefined || id === null) + throw new Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(model); + + let options_ = { + body: content_, + method: "PUT", + headers: { + "Content-Type": "application/json", + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processPut(_response); + }); + } + + protected processPut(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + return result200; + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } + + delete(id: string): Promise { + let url_ = this.baseUrl + "/api/Product/{id}"; + if (id === undefined || id === null) + throw new Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ = { + method: "DELETE", + headers: { + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processDelete(_response); + }); + } + + protected processDelete(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + return result200; + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } +} + +export class SettingsClient { + private http: { fetch(url: RequestInfo, init?: RequestInit): Promise }; + private baseUrl: string; + protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined; + + constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise }) { + this.http = http ? http : window; + this.baseUrl = baseUrl !== undefined && baseUrl !== null ? baseUrl : "http://localhost:5000"; + } + + get(): Promise { + let url_ = this.baseUrl + "/api/Settings"; + url_ = url_.replace(/[?&]$/, ""); + + let options_ = { + method: "GET", + headers: { + "Accept": "application/json" + } + }; + + return this.http.fetch(url_, options_).then((_response: Response) => { + return this.processGet(_response); + }); + } + + protected processGet(response: Response): Promise { + const status = response.status; + let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; + if (status === 200) { + return response.text().then((_responseText) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); + return result200; + }); + } else if (status !== 200 && status !== 204) { + return response.text().then((_responseText) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + }); + } + return Promise.resolve(null); + } +} + +export interface CartCustomerListItem { + productID: string; + productName?: string | undefined; + productPrice: number; + customerName?: string | undefined; + customerEmail?: string | undefined; + quantity: number; +} + +export interface CartListItem { + productID: string; + productName?: string | undefined; + productPrice: number; + quantity: number; +} + +export interface CartCreateUpdateModel { + customerID: string; + productID: string; + quantity: number; +} + +export interface CartDeleteModel { + customerID: string; + productID: string; +} + +export interface CustomerListItem { + customerID: string; + name?: string | undefined; + email?: string | undefined; +} + +export interface CustomerCreateUpdateModel { + name: string; + email: string; +} + +export interface ProductListItem { + productID: string; + name?: string | undefined; + price: number; +} + +export interface ProductCreateUpdateModel { + name: string; + price: number; +} + +export class ApiException extends Error { + message: string; + status: number; + response: string; + headers: { [key: string]: any; }; + result: any; + + constructor(message: string, status: number, response: string, headers: { [key: string]: any; }, result: any) { + super(); + + this.message = message; + this.status = status; + this.response = response; + this.headers = headers; + this.result = result; + } + + protected isApiException = true; + + static isApiException(obj: any): obj is ApiException { + return obj.isApiException === true; + } +} + +function throwException(message: string, status: number, response: string, headers: { [key: string]: any; }, result?: any): any { + if (result !== null && result !== undefined) + throw result; + else + throw new ApiException(message, status, response, headers, null); +} \ No newline at end of file diff --git a/Next/package.json b/Next/package.json index 4af4505..e82f6e8 100644 --- a/Next/package.json +++ b/Next/package.json @@ -12,13 +12,18 @@ "author": "", "license": "ISC", "dependencies": { + "@fortawesome/fontawesome-svg-core": "^1.2.35", + "@fortawesome/free-solid-svg-icons": "^5.15.3", + "@fortawesome/react-fontawesome": "^0.1.14", "axios": "^0.21.1", "bootstrap": "^5.0.0-beta3", "mobx": "^6.1.8", "mobx-react": "^7.1.0", "next": "^10.0.9", "react": "^17.0.2", - "react-dom": "^17.0.2" + "react-dom": "^17.0.2", + "react-fontawesome": "^1.7.1", + "sweetalert2": "^10.15.6" }, "devDependencies": { "@babel/core": "^7.13.10", diff --git a/Next/pages/customer.tsx b/Next/pages/customer.tsx deleted file mode 100644 index 949162a..0000000 --- a/Next/pages/customer.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import React from 'react'; -import axios from 'axios'; - -import { Layout } from './shared/Layout'; - -interface CustomerListItem { - customerID: string; - name: string; - email: string; -} -function RenderCustomerListItemRows(customers: CustomerListItem[]) { - let rows = customers.map(x => { - return ( - - {x.name} - {x.email} - - ); - }) - return ( - - {rows} - - ) -} -class Customer extends React.Component<{}, {customer: CustomerListItem[] }> { - constructor(props) { - super(props); - this.state = { - customer: [], - } - } - async componentDidMount() { - try { - let data = await axios.get("http://localhost:5000/api/customer");0 - console.log(data.data); - this.setState({ - customer: data.data - }); - } catch (error) { - this.setState({ - customer: [], - }); - } - } - render() { - return ( - - - - - - {RenderCustomerListItemRows(this.state.customer)} -
NameEmail
- ); - } -} - -export default function CustomerPage() { - return ( - - - - ) -} \ No newline at end of file diff --git a/Next/pages/customer/create.tsx b/Next/pages/customer/create.tsx new file mode 100644 index 0000000..4edb69d --- /dev/null +++ b/Next/pages/customer/create.tsx @@ -0,0 +1,122 @@ +import React, { ChangeEvent } from 'react'; +import { Layout } from '../shared/Layout'; +import { CustomerClient } from '../../APIClient'; +import Swal from 'sweetalert2'; + +function Errors({ errors }) { + return errors.map(x => ( +
  • {x}
  • + )); +} +class CreateCustomer extends React.Component<{}, { + form: { + name: string, + email: string, + }, + errors: string[], + busy: boolean, +}> { + constructor(props) { + super(props) + this.state = { + form: { + name: "", + email: "", + }, + errors: [], + busy: false, + } + } + onNameChanged(e: ChangeEvent) { + this.setState({ + form: { + name: e.target.value, + email: this.state.form.email, + } + }); + } + onEmailChanged(e: ChangeEvent) { + this.setState({ + form: { + name: this.state.form.name, + email: e.target.value + } + }); + } + async validate() { + let errors: string[] = []; + if (!this.state.form.name) { + errors.push("Name required"); + } + if (!this.state.form.email) { + errors.push("Email required"); + } + await new Promise((resolve) => { + this.setState({ + errors + }, () => resolve(undefined)); + }) + return errors.length == 0; + } + async onSubmit(e) { + e.preventDefault(); + if (await this.validate()) { + await new Promise((resolve) => { + this.setState({ + busy: true, + }, () => resolve(undefined)); + }) + try { + const form = this.state.form; + const client = new CustomerClient(); + await client.post({ + name: form.name, + email: form.email, + }) + Swal.fire({ + title: "Submitted!", + text: "Customer is now in database", + }) + } catch (error) { + + } finally { + await new Promise((resolve) => { + this.setState({ + busy: false, + }, () => resolve(undefined)); + }) + + } + } + } + render() { + return ( +
    +
    +
    + + +
    +
    + + +
    +
    + +
    +
  • + +
  • +
    +
    + ) + } +} + +export default function CreateCustomerPage() { + return ( + + + + ) +} \ No newline at end of file diff --git a/Next/pages/customer/index.tsx b/Next/pages/customer/index.tsx new file mode 100644 index 0000000..1bf904d --- /dev/null +++ b/Next/pages/customer/index.tsx @@ -0,0 +1,106 @@ +import React from 'react'; +import axios from 'axios'; +import { CustomerClient, CustomerListItem } from '../../APIClient'; +import { Layout } from '../shared/Layout'; +import Swal from 'sweetalert2'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faTrash } from '@fortawesome/free-solid-svg-icons'; + +const DeleteCustomerButton: React.FunctionComponent<{ + customerID: string, + onDelete: (val) => void + +}> = ({ customerID, onDelete }) => { + const onClickDelete = async () => { + const result = await Swal.fire({ + title: 'Confirm delete?', + text: 'Delete customer?', + icon: 'warning', + showCancelButton: true, + }) + if (result.isConfirmed) { + onDelete(customerID); + } + } + return ( + + ); +} +const CustomerListItemRows: React.FunctionComponent<{ + customers: CustomerListItem[], + onDelete: (val) => void, +}> = ({ customers, onDelete }) => { + let rows = customers.map(x => { + return ( + + {x.name} + {x.email} + + + ); + }) + return ( + + {rows} + + ) +} +class Customer extends React.Component<{}, { customer: CustomerListItem[] }> { + constructor(props) { + super(props); + this.state = { + customer: [], + } + } + async componentDidMount() { + this.getCustomers(); + } + async getCustomers() { + try { + const client = new CustomerClient(); + let data = await client.getAll(); + console.log(data); + this.setState({ + customer: data + }); + } catch (error) { + this.setState({ + customer: [], + }); + } + } + async deleteCustomer(customerId) { + try { + const client = new CustomerClient(); + await client.delete(customerId); + let customer = this.state.customer.filter(x => x.customerID != customerId); + this.setState({ + customer + }) + } catch (error) { + alert(error); + } + } + render() { + return ( + + + + + + + +
    NameEmail
    + ); + } +} + +export default function CustomerPage() { + return ( + + + + ) +} \ No newline at end of file diff --git a/Next/yarn.lock b/Next/yarn.lock index 151ec27..f92cf47 100644 --- a/Next/yarn.lock +++ b/Next/yarn.lock @@ -259,6 +259,32 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" +"@fortawesome/fontawesome-common-types@^0.2.35": + version "0.2.35" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.35.tgz#01dd3d054da07a00b764d78748df20daf2b317e9" + integrity sha512-IHUfxSEDS9dDGqYwIW7wTN6tn/O8E0n5PcAHz9cAaBoZw6UpG20IG/YM3NNLaGPwPqgjBAFjIURzqoQs3rrtuw== + +"@fortawesome/fontawesome-svg-core@^1.2.35": + version "1.2.35" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.35.tgz#85aea8c25645fcec88d35f2eb1045c38d3e65cff" + integrity sha512-uLEXifXIL7hnh2sNZQrIJWNol7cTVIzwI+4qcBIq9QWaZqUblm0IDrtSqbNg+3SQf8SMGHkiSigD++rHmCHjBg== + dependencies: + "@fortawesome/fontawesome-common-types" "^0.2.35" + +"@fortawesome/free-solid-svg-icons@^5.15.3": + version "5.15.3" + resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.3.tgz#52eebe354f60dc77e0bde934ffc5c75ffd04f9d8" + integrity sha512-XPeeu1IlGYqz4VWGRAT5ukNMd4VHUEEJ7ysZ7pSSgaEtNvSo+FLurybGJVmiqkQdK50OkSja2bfZXOeyMGRD8Q== + dependencies: + "@fortawesome/fontawesome-common-types" "^0.2.35" + +"@fortawesome/react-fontawesome@^0.1.14": + version "0.1.14" + resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.14.tgz#bf28875c3935b69ce2dc620e1060b217a47f64ca" + integrity sha512-4wqNb0gRLVaBm/h+lGe8UfPPivcbuJ6ecI4hIgW0LjI7kzpYB9FkN0L9apbVzg+lsBdcTf0AlBtODjcSX5mmKA== + dependencies: + prop-types "^15.7.2" + "@hapi/accept@5.0.1": version "5.0.1" resolved "https://registry.yarnpkg.com/@hapi/accept/-/accept-5.0.1.tgz#068553e867f0f63225a506ed74e899441af53e10" @@ -1422,7 +1448,7 @@ process@0.11.10, process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= -prop-types@15.7.2: +prop-types@15.7.2, prop-types@^15.5.6, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -1507,6 +1533,13 @@ react-dom@^17.0.2: object-assign "^4.1.1" scheduler "^0.20.2" +react-fontawesome@^1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/react-fontawesome/-/react-fontawesome-1.7.1.tgz#f74f5a338fef3ee3b379820109c1cba47290f035" + integrity sha512-kottReWW1I9Uupub6A5YX4VK7qfpFnEjAcm5zB4Aepst7iofONT27GJYdTcRsj7q5uQu9PXBL7GsxAFKANNUVg== + dependencies: + prop-types "^15.5.6" + react-is@16.13.1, react-is@^16.8.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" @@ -1757,6 +1790,11 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +sweetalert2@^10.15.6: + version "10.15.6" + resolved "https://registry.yarnpkg.com/sweetalert2/-/sweetalert2-10.15.6.tgz#8fe309af76543f7d8151a2e57a226f1cceb51a4e" + integrity sha512-elLyVvVwBBsgkT0NrxiiVuEv077gqGhm7WEdBjXRHN+TOX+MoC4LpDW2kbdSeJtjjU1sPdqGKfGLoJElIXfVWA== + timers-browserify@^2.0.4: version "2.0.12" resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" diff --git a/TestAppRuna/API/CustomerController.cs b/TestAppRuna/API/CustomerController.cs index ce5da20..46fe4bb 100644 --- a/TestAppRuna/API/CustomerController.cs +++ b/TestAppRuna/API/CustomerController.cs @@ -14,6 +14,7 @@ namespace TestAppRuna.API { [Route("api/[controller]")] [ApiController] + // [Authorize("nanaoaccounts")] public class CustomerController : ControllerBase { public CustomerController(ShopDbContext shopDbContext) diff --git a/TestAppRuna/Shop.sqlite.db b/TestAppRuna/Shop.sqlite.db index 42fd388..a437520 100644 Binary files a/TestAppRuna/Shop.sqlite.db and b/TestAppRuna/Shop.sqlite.db differ diff --git a/TestAppRuna/Startup.cs b/TestAppRuna/Startup.cs index 284d133..1eda347 100644 --- a/TestAppRuna/Startup.cs +++ b/TestAppRuna/Startup.cs @@ -53,9 +53,13 @@ namespace TestAppRuna ); services.AddCors(options => { options.AddPolicy("BelajarNextJS", policy => { - policy.WithOrigins("http://localhost:3000"); + policy.WithOrigins("http://localhost:3000") + .AllowAnyHeader() + .AllowAnyMethod(); }); }); + services.AddSwaggerDocument(settings => { + }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -79,10 +83,15 @@ namespace TestAppRuna } app.UseStaticFiles(); - app.UseOpenApi(); + app.UseOpenApi(settings => { + settings.DocumentName = "v1"; + settings.Path = "/swagger/v1/swagger.json"; + }); + app.UseSwaggerUi3(settings => { settings.DocumentTitle = "TestAppRuna"; + settings.DocumentPath = "/swagger/v1/swagger.json"; }); app.UseRouting(); diff --git a/package.json b/package.json new file mode 100644 index 0000000..b6833a4 --- /dev/null +++ b/package.json @@ -0,0 +1,7 @@ +{ + "dependencies": { + "react-fontawesome": "^1.7.1", + "sweetalert2": "^10.15.6", + "validate.js": "^0.13.1" + } +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..36c3e2a --- /dev/null +++ b/yarn.lock @@ -0,0 +1,51 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"js-tokens@^3.0.0 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +prop-types@^15.5.6: + version "15.7.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" + integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.8.1" + +react-fontawesome@^1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/react-fontawesome/-/react-fontawesome-1.7.1.tgz#f74f5a338fef3ee3b379820109c1cba47290f035" + integrity sha512-kottReWW1I9Uupub6A5YX4VK7qfpFnEjAcm5zB4Aepst7iofONT27GJYdTcRsj7q5uQu9PXBL7GsxAFKANNUVg== + dependencies: + prop-types "^15.5.6" + +react-is@^16.8.1: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +sweetalert2@^10.15.6: + version "10.15.6" + resolved "https://registry.yarnpkg.com/sweetalert2/-/sweetalert2-10.15.6.tgz#8fe309af76543f7d8151a2e57a226f1cceb51a4e" + integrity sha512-elLyVvVwBBsgkT0NrxiiVuEv077gqGhm7WEdBjXRHN+TOX+MoC4LpDW2kbdSeJtjjU1sPdqGKfGLoJElIXfVWA== + +validate.js@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/validate.js/-/validate.js-0.13.1.tgz#b58bfac04a0f600a340f62e5227e70d95971e92a" + integrity sha512-PnFM3xiZ+kYmLyTiMgTYmU7ZHkjBZz2/+F0DaALc/uUtVzdCt1wAosvYJ5hFQi/hz8O4zb52FQhHZRC+uVkJ+g==