diff --git a/data/avored.db/.gitkeep b/data/avored.db/.gitkeep
deleted file mode 100644
index e69de29b..00000000
diff --git a/public/css/app.css b/public/css/app.css
index a211bdb7..10b2584c 100644
--- a/public/css/app.css
+++ b/public/css/app.css
@@ -918,6 +918,10 @@ select {
margin-bottom: auto;
}
+.ml-1 {
+ margin-left: 0.25rem;
+}
+
.ml-2 {
margin-left: 0.5rem;
}
@@ -990,10 +994,6 @@ select {
margin-top: 2rem;
}
-.ml-1 {
- margin-left: 0.25rem;
-}
-
.block {
display: block;
}
diff --git a/react-admin/package-lock.json b/react-admin/package-lock.json
index 16693ff6..7f0e4e20 100644
--- a/react-admin/package-lock.json
+++ b/react-admin/package-lock.json
@@ -8,6 +8,7 @@
"name": "react-admin",
"version": "0.1.0",
"dependencies": {
+ "@headlessui/react": "^1.7.17",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
@@ -2383,6 +2384,21 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
+ "node_modules/@headlessui/react": {
+ "version": "1.7.17",
+ "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.17.tgz",
+ "integrity": "sha512-4am+tzvkqDSSgiwrsEpGWqgGo9dz8qU5M3znCkC4PgkpY4HcCZzEDEvozltGGGHIKl9jbXbZPSH5TWn4sWJdow==",
+ "dependencies": {
+ "client-only": "^0.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "react": "^16 || ^17 || ^18",
+ "react-dom": "^16 || ^17 || ^18"
+ }
+ },
"node_modules/@humanwhocodes/config-array": {
"version": "0.11.13",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
@@ -6036,6 +6052,11 @@
"node": ">=0.10.0"
}
},
+ "node_modules/client-only": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
+ "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
+ },
"node_modules/cliui": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
@@ -19501,6 +19522,14 @@
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz",
"integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA=="
},
+ "@headlessui/react": {
+ "version": "1.7.17",
+ "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.17.tgz",
+ "integrity": "sha512-4am+tzvkqDSSgiwrsEpGWqgGo9dz8qU5M3znCkC4PgkpY4HcCZzEDEvozltGGGHIKl9jbXbZPSH5TWn4sWJdow==",
+ "requires": {
+ "client-only": "^0.0.1"
+ }
+ },
"@humanwhocodes/config-array": {
"version": "0.11.13",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
@@ -22211,6 +22240,11 @@
}
}
},
+ "client-only": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
+ "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
+ },
"cliui": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
diff --git a/react-admin/package.json b/react-admin/package.json
index cd665523..640aafb3 100644
--- a/react-admin/package.json
+++ b/react-admin/package.json
@@ -8,6 +8,7 @@
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
+ "@headlessui/react": "^1.7.17",
"react-router-dom": "^6.20.1",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
diff --git a/react-admin/src/App.js b/react-admin/src/App.js
index 7ff7cf7e..173df8d1 100644
--- a/react-admin/src/App.js
+++ b/react-admin/src/App.js
@@ -3,6 +3,9 @@ import {BrowserRouter, Navigate, Route, Routes} from 'react-router-dom';
import Dashboard from './pages/Dashboard'
import Login from './pages/auth/Login'
import Home from "./pages/Home";
+import AppLayout from "./layouts/AppLayout";
+import PageTable from "./pages/page/PageTable";
+import PageCreate from "./pages/page/PageCreate";
function App() {
return (
@@ -10,8 +13,15 @@ function App() {
{/*} />*/}
} />
- } />
+
} />
+
+ }>
+ } />
+ } />
+ } />
+
+
);
diff --git a/react-admin/src/layouts/AppLayout.jsx b/react-admin/src/layouts/AppLayout.jsx
new file mode 100644
index 00000000..1e32e20b
--- /dev/null
+++ b/react-admin/src/layouts/AppLayout.jsx
@@ -0,0 +1,14 @@
+import AppHeader from "./partials/AppHeader";
+import AppSidebar from "./partials/AppSidebar";
+
+function AppLayout() {
+ return (
+
+ );
+}
+
+export default AppLayout;
diff --git a/react-admin/src/layouts/partials/AppHeader.jsx b/react-admin/src/layouts/partials/AppHeader.jsx
new file mode 100644
index 00000000..7dbc9ab9
--- /dev/null
+++ b/react-admin/src/layouts/partials/AppHeader.jsx
@@ -0,0 +1,22 @@
+import logo from "../../assets/logo_only.svg";
+
+function AppHeader() {
+ return (
+
+ );
+}
+
+export default AppHeader;
diff --git a/react-admin/src/layouts/partials/AppSidebar.jsx b/react-admin/src/layouts/partials/AppSidebar.jsx
new file mode 100644
index 00000000..0431b314
--- /dev/null
+++ b/react-admin/src/layouts/partials/AppSidebar.jsx
@@ -0,0 +1,114 @@
+import logo from "../../assets/logo_only.svg";
+import FeatherIcon from "feather-icons-react";
+import {Link, Outlet} from "react-router-dom";
+
+function AppSidebar() {
+ return (
+
+ );
+}
+
+export default AppSidebar;
diff --git a/react-admin/src/pages/Dashboard.jsx b/react-admin/src/pages/Dashboard.jsx
index ad6e1a74..4910c3c2 100644
--- a/react-admin/src/pages/Dashboard.jsx
+++ b/react-admin/src/pages/Dashboard.jsx
@@ -3,132 +3,10 @@ import FeatherIcon from 'feather-icons-react'
function Dashboard() {
return (
-
-
-
-
-
-
-
- Dashboard content goes here
-
-
+
+
+ Dashboard outlet content goes here
-
-
)
}
diff --git a/react-admin/src/pages/auth/Login.jsx b/react-admin/src/pages/auth/Login.jsx
index 0b9a5f98..d3ba2398 100644
--- a/react-admin/src/pages/auth/Login.jsx
+++ b/react-admin/src/pages/auth/Login.jsx
@@ -28,6 +28,7 @@ function Login() {
body: JSON.stringify({email: email, password: password})
}))
const login_response = await response.json()
+ console.log(login_response)
if (login_response.status) {
localStorage.setItem("AUTH_TOKEN", login_response.data)
return redirect("/admin");
diff --git a/react-admin/src/pages/page/PageCreate.jsx b/react-admin/src/pages/page/PageCreate.jsx
new file mode 100644
index 00000000..1fd9b5e1
--- /dev/null
+++ b/react-admin/src/pages/page/PageCreate.jsx
@@ -0,0 +1,18 @@
+import {useEffect, useState} from "react";
+import {Link} from "react-router-dom";
+
+function PageCreate() {
+
+
+ return (
+
+
+
+ Page Create Form goes here
+
+
+
+ )
+}
+
+export default PageCreate
\ No newline at end of file
diff --git a/react-admin/src/pages/page/PageTable.jsx b/react-admin/src/pages/page/PageTable.jsx
new file mode 100644
index 00000000..ec0d2ddc
--- /dev/null
+++ b/react-admin/src/pages/page/PageTable.jsx
@@ -0,0 +1,93 @@
+import {useEffect, useState} from "react";
+import {Link} from "react-router-dom";
+
+function PageTable() {
+ const [pages, setPages] = useState([]);
+
+ const getFormattedDate = ((date) => {
+ var date = new Date(date);
+
+ return `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`;
+ })
+
+ useEffect(() => {
+ const mounted = (async () => {
+ const response = await fetch('http://localhost:8080/api/page', {
+ method: 'get',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': 'Bearer ' + localStorage.getItem("AUTH_TOKEN"),
+ }
+ })
+ return await response.json()
+ })
+
+ mounted().then((res) => {
+ console.log(res.data)
+ setPages(res.data)
+ })
+
+ }, [])
+
+ return (
+
+
+
+
+ Pages
+
+
+ Create
+
+
+
+
+
+
+
+
+ ID |
+ Name |
+ Identifier |
+ Created at |
+ Updated at |
+ Created by |
+ Updated by |
+ Action |
+
+
+
+ {pages.map((page) => {
+ return (
+
+ {page.id} |
+ {page.name} |
+ {page.identifier} |
+
+ {getFormattedDate(page.created_at)}
+ |
+
+ {getFormattedDate(page.updated_at)}
+ |
+ {page.created_by} |
+ {page.updated_by} |
+
+
+ Edit
+
+
+ |
+
+ )
+ })}
+
+
+
+
+
+ )
+}
+
+export default PageTable
\ No newline at end of file
diff --git a/src/api/rest_api/handlers/mod.rs b/src/api/rest_api/handlers/mod.rs
index 81751079..5baa5b5b 100644
--- a/src/api/rest_api/handlers/mod.rs
+++ b/src/api/rest_api/handlers/mod.rs
@@ -1,3 +1,5 @@
pub mod health_check_api_handler;
pub mod component_all_api_handler;
pub mod admin_user;
+pub mod page;
+
diff --git a/src/api/rest_api/handlers/page/mod.rs b/src/api/rest_api/handlers/page/mod.rs
new file mode 100644
index 00000000..f8a96c30
--- /dev/null
+++ b/src/api/rest_api/handlers/page/mod.rs
@@ -0,0 +1,2 @@
+pub mod page_table_api_handler;
+pub mod request;
\ No newline at end of file
diff --git a/src/api/rest_api/handlers/page/page_table_api_handler.rs b/src/api/rest_api/handlers/page/page_table_api_handler.rs
new file mode 100644
index 00000000..3da5d9a9
--- /dev/null
+++ b/src/api/rest_api/handlers/page/page_table_api_handler.rs
@@ -0,0 +1,19 @@
+use std::sync::Arc;
+use axum::extract::{Query, State};
+use axum::Json;
+use crate::api::rest_api::handlers::page::request::page_table_request::PageTableRequest;
+use crate::avored_state::AvoRedState;
+use crate::error::Result;
+use crate::models::page_model::PagePagination;
+
+pub async fn page_table_api_handler(
+ state: State
>,
+ Query(query_param): Query,
+) -> Result> {
+ println!("->> {:<12} - page_table_api_handler", "HANDLER");
+
+ let current_page = query_param.page.unwrap_or(1);
+ let page_pagination = state.page_service.paginate(&state.db, current_page).await?;
+
+ Ok(Json(page_pagination))
+}
diff --git a/src/api/rest_api/handlers/page/request/mod.rs b/src/api/rest_api/handlers/page/request/mod.rs
new file mode 100644
index 00000000..c89747a8
--- /dev/null
+++ b/src/api/rest_api/handlers/page/request/mod.rs
@@ -0,0 +1 @@
+pub mod page_table_request;
\ No newline at end of file
diff --git a/src/api/rest_api/handlers/page/request/page_table_request.rs b/src/api/rest_api/handlers/page/request/page_table_request.rs
new file mode 100644
index 00000000..8be1a0f6
--- /dev/null
+++ b/src/api/rest_api/handlers/page/request/page_table_request.rs
@@ -0,0 +1,6 @@
+use serde::Deserialize;
+
+#[derive(Deserialize, Debug)]
+pub struct PageTableRequest {
+ pub page: Option,
+}
diff --git a/src/api/rest_api/rest_api_routes.rs b/src/api/rest_api/rest_api_routes.rs
index 12b96d64..a73a2557 100644
--- a/src/api/rest_api/rest_api_routes.rs
+++ b/src/api/rest_api/rest_api_routes.rs
@@ -4,12 +4,15 @@ use axum::{routing::get, Router, middleware};
use axum::routing::post;
use axum::http::header::{AUTHORIZATION, CONTENT_TYPE};
use axum::http::header::HeaderValue;
-use crate::api::rest_api::handlers::component_all_api_handler::component_all_api_handler;
-use crate::api::rest_api::handlers::health_check_api_handler::health_check_api_handler;
-use crate::api::rest_api::handlers::admin_user::admin_user_login_api_handler::admin_user_login_api_handler;
use crate::avored_state::AvoRedState;
use crate::middleware::require_jwt_authentication::require_jwt_authentication;
use tower_http::cors::CorsLayer;
+use crate::api::rest_api::handlers::{
+ page::page_table_api_handler::page_table_api_handler,
+ admin_user::admin_user_login_api_handler::admin_user_login_api_handler,
+ component_all_api_handler::component_all_api_handler,
+ health_check_api_handler::health_check_api_handler
+};
pub fn rest_api_routes(state: Arc) -> Router {
@@ -29,6 +32,7 @@ pub fn rest_api_routes(state: Arc) -> Router {
]);
Router::new()
+ .route("/api/page", get(page_table_api_handler))
.route("/api/component-all", get(component_all_api_handler))
.route_layer(middleware::from_fn_with_state(
state.clone(),