Skip to content

Commit 6f839fa

Browse files
committed
Added: Expired token, config debounce. Update: ProductController Query
1 parent 5beddc5 commit 6f839fa

File tree

11 files changed

+70
-57
lines changed

11 files changed

+70
-57
lines changed

backend/app/Http/Controllers/ProductController.php

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,10 @@ public function index(Request $request)
1919
$perPage = $request->get('showing', 10);
2020
$search = $request->get('search', '');
2121

22-
$query = Product::query();
23-
24-
if (!empty($search)) {
25-
$query->where('name', 'like', "%{$search}%")
26-
->orWhere('description', 'like', "%{$search}%");
27-
}
28-
29-
$data = $query->latest()->paginate($perPage);
30-
22+
$data = Product::where(function($query) use ($search) {
23+
$query->where('name', 'LIKE', "%{$search}%");
24+
$query->orWhere('description', 'LIKE', "%{$search}%");
25+
})->latest()->paginate($perPage);
3126

3227
return response()->json([
3328
'data' => $data,
@@ -44,39 +39,25 @@ public function index(Request $request)
4439
}
4540
}
4641

47-
/**
48-
* Show the form for creating a new resource.
49-
*/
50-
public function create()
51-
{
52-
try
53-
{
54-
55-
}
56-
catch (Exception $e)
57-
{
58-
return response()->json([
59-
'data' => [],
60-
'success' => false,
61-
'message' => $e->getMessage()
62-
], JsonResponse::HTTP_INTERNAL_SERVER_ERROR);
63-
}
64-
}
65-
6642
/**
6743
* Store a newly created resource in storage.
6844
*/
6945
public function store(Request $request)
7046
{
47+
$validatedData = $request->validate([
48+
'name' => 'required|max:5',
49+
'price' => 'numeric'
50+
]);
51+
7152
try
7253
{
73-
$data = Product::create($request->all());
54+
$data = Product::create($validatedData);
7455

7556
return response()->json([
7657
'data' => $data,
7758
'success' => true,
7859
'message' => 'Data created successfully'
79-
], JsonResponse::HTTP_OK);
60+
], JsonResponse::HTTP_CREATED);
8061
}
8162
catch (Exception $e)
8263
{

frontend/src/components/Navigation.jsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1+
import axios from "axios";
2+
import NavLink from "./NavLink";
13
import React, { useState, useEffect, useRef } from "react";
24
import { Link, useNavigate } from "react-router-dom";
35

4-
import NavLink from "./NavLink";
5-
6-
import axios from "axios";
6+
import { getTokenWithExpiration } from "../pages/Auth/Session";
77

88
export default function Navigation() {
99
const [user, setUser] = useState({});
1010
const baseURL = "http://127.0.0.1:8000/api";
1111

1212
const navigate = useNavigate();
13-
const token = localStorage.getItem("token");
13+
const token = getTokenWithExpiration("token");
1414

1515
const [dropdownOpen, setDropdownOpen] = useState(false);
1616
const dropdownRef = useRef(null);
@@ -88,14 +88,14 @@ export default function Navigation() {
8888
</a>
8989
<div className="dropdown-menu dropdown-menu-right">
9090
<div className="dropdown-title">
91-
Logged in 5 min ago
91+
ROLE: {user.role}
9292
</div>
93-
<a
94-
href="features-profile.html"
93+
<Link
94+
to="/profile"
9595
className="dropdown-item has-icon"
9696
>
9797
<i className="far fa-user"></i> Profile
98-
</a>
98+
</Link>
9999
<div className="dropdown-divider"></div>
100100
<a
101101
onClick={logoutHandler}

frontend/src/components/Router.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import AuthLayout from "../pages/Layout/AuthLayout";
1010
import MainLayout from "../pages/Layout/MainLayout";
1111
import Error403 from "../pages/Error/403";
1212
import Error404 from "../pages/Error/404";
13+
1314
export default function Router() {
1415
return (
1516
<Routes>

frontend/src/config/appConfig.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const appConfig = {
2+
debounceTimeout: 750,
3+
};
4+
5+
export default appConfig;

frontend/src/pages/AdvancedFeature.jsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import React from "react";
22
import Case from "../components/Case";
33
import { useEffect } from "react";
4-
import MainLayout from "./Layout/MainLayout";
54

65
export default function AdvancedFeature() {
76
useEffect(() => {

frontend/src/pages/Auth/Login.jsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1+
import axios from "axios";
2+
import Swal from "sweetalert2";
13
import React, { useEffect, useState } from "react";
2-
34
import { Link, useNavigate } from "react-router-dom";
4-
import Swal from "sweetalert2";
55
import withReactContent from "sweetalert2-react-content";
66

7-
import axios from "axios";
8-
import AuthLayout from "../Layout/AuthLayout";
7+
import { setTokenWithExpiration, getTokenWithExpiration } from "./Session";
98

109
export default function Login() {
1110
const baseURL = "http://127.0.0.1:8000/api";
@@ -15,7 +14,7 @@ export default function Login() {
1514

1615
useEffect(() => {
1716
document.title = "Login";
18-
if (localStorage.getItem("token")) {
17+
if (getTokenWithExpiration("token")) {
1918
//redirect page dashboard
2019
window.location.href = "/dashboard";
2120
}
@@ -73,7 +72,7 @@ export default function Login() {
7372
})
7473
.then((response) => {
7574
if (response.status === 200) {
76-
localStorage.setItem("token", response.data.token);
75+
setTokenWithExpiration("token", response.data.token);
7776
MySwal.fire({
7877
title: "Success!",
7978
text: "Login successfully",

frontend/src/pages/Auth/Register.jsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1+
import axios from "axios";
2+
import Swal from "sweetalert2";
13
import React, { useEffect, useState } from "react";
2-
34
import { Link, useNavigate } from "react-router-dom";
4-
import Swal from "sweetalert2";
55
import withReactContent from "sweetalert2-react-content";
66

7-
import axios from "axios";
8-
import AuthLayout from "../Layout/AuthLayout";
9-
107
export default function Register() {
118
const baseURL = "http://127.0.0.1:8000/api";
129

frontend/src/pages/Auth/Session.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
export function setTokenWithExpiration(key, token) {
2+
const now = new Date();
3+
const expirationTime = now.getTime() + 60 * 60 * 1000;
4+
const item = token + "|" + expirationTime;
5+
localStorage.setItem(key, item);
6+
}
7+
8+
export function getTokenWithExpiration(key) {
9+
const item = localStorage.getItem(key);
10+
if (!item) {
11+
return null;
12+
}
13+
const [token, expirationTime] = item.split("|");
14+
const now = new Date();
15+
if (now.getTime() > expirationTime) {
16+
localStorage.removeItem(key);
17+
return null;
18+
}
19+
return token;
20+
}
21+
22+
export function getTokenExpirationTime(key) {
23+
const item = localStorage.getItem(key);
24+
if (!item) {
25+
return null;
26+
}
27+
const [_, expirationTime] = item.split("|");
28+
const now = new Date();
29+
const remainingSeconds = Math.round(
30+
(expirationTime - now.getTime()) / 1000
31+
);
32+
return remainingSeconds > 0 ? remainingSeconds : null;
33+
}

frontend/src/pages/Dashboard.jsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React from "react";
22
import Case from "../components/Case";
3-
43
import { useEffect } from "react";
54

65
export default function Dashboard() {

frontend/src/pages/Layout/MainLayout.jsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
import React from "react";
2-
import Navbar from "../../components/Navbar";
3-
import Sidebar from "../../components/Sidebar";
42
import Footer from "../../components/Footer";
53
import Navigation from "../../components/Navigation";
64

0 commit comments

Comments
 (0)