
Hey!
Are you frustrating of making admin panel for website?
Here I have something new for you….
- index.php
<?php
require "lib/Core.php";
require PATH_LIB . "PAGE-top.php";?>
YOUR DASHBOARD HERE
<?php require PATH_LIB . "PAGE-bottom.php"; ?>
- Login.php
<?php
// (A) INIT
require "lib/Core.php";
$_ISLOGIN = 1;
require PATH_LIB . "PAGE-top.php"; ?>
<!-- (B) JAVASCRIPT -->
<script>
function login () {
admin.ajax({
url : url.host + "ajax-session.php",
data : {
req : "in",
email : document.getElementById("user_email").value,
password : document.getElementById("user_password").value
},
ok : () => { location.reload(); }
});
return false;
}
</script>
<!-- (C) CSS -->
<style>
#login-form {
max-width: 320px; margin: 0 auto; padding: 20px;
background: #eee; border: 1px solid #ccc;
}
#login-form input { width: 100%; margin-top: 20px; }
</style>
<!-- (D) LOGIN FORM -->
<form id="login-form" onsubmit="return login();">
<h1>LOGIN</h1>
<input type="email" placeholder="Email" id="user_email" required />
<input type="password" placeholder="Password" id="user_password" required />
<input type="submit" value="Sign In"/>
</form>
<?php require PATH_LIB . "PAGE-bottom.php"; ?>
- ajax-session.php
<?php
require "lib/Core.php";
if (isset($_POST["req"])) { switch ($_POST["req"]) {
// (A) INVALID REQUEST
default: exit("INVALID REQUEST");
// (B) LOGIN
case "in":
// (B1) ALREADY SIGNED IN
if (isset($_SESSION["user"])) { exit("OK"); }
// (B2) VERIFY
else {
require PATH_LIB . "LIB-database.php";
$DB = new DB();
$user = $DB->fetch(
"SELECT * FROM `users` WHERE `user_email`=?", [$_POST["email"]]
);
$pass = is_array($user);
if ($pass) { $pass = password_verify($_POST["password"], $user["user_password"]); }
if ($pass) {
$_SESSION["user"] = [];
foreach ($user as $k=>$v) { if ($k!="user_password") {
$_SESSION["user"][$k] = $v;
}}
exit("OK");
}
exit("Invalid user/password");
}
// (C) LOGOUT
case "out":
unset($_SESSION["user"]);
exit("OK");
}}
- mypage.php
<?php
require "lib/Core.php";
require PATH_LIB . "PAGE-top.php"; ?>
<h1>MY PAGE</h1>
<p>Do something.</p>
<?php require PATH_LIB . "PAGE-bottom.php"; ?>
Now create two folder ‘lib’ & ‘public’ in that directory where you made that file.
- core.php
<?php
// (A) ERROR HANDLING - CHANGE TO YOUR OWN
error_reporting(E_ALL & ~E_NOTICE);
ini_set("display_errors", 1);
// ini_set("log_errors", 1);
// ini_set("error_log", "PATH/error.log");
// (B) DATABASE SETTINGS - CHANGE TO YOUR OWN
define("DB_HOST", "localhost");
define("DB_NAME", "test");
define("DB_CHARSET", "utf8");
define("DB_USER", "root");
define("DB_PASSWORD", "");
// (C) URL
define("URL_HOST", "http://localhost/"); // CHANGE TO YOUR OWN
define("URL_PUBLIC", URL_HOST . "public/");
// (D) FILE PATHS
define("PATH_LIB", __DIR__ . DIRECTORY_SEPARATOR);
define("PATH_BASE", dirname(PATH_LIB) . DIRECTORY_SEPARATOR);
// (E) START SESSION
session_start();
- .htaccess
Deny from all
- LIB-database.php
<?php
class DB {
// (A) CONSTRUCTOR - CONNECT TO DATABASE
private $pdo = null;
private $stmt = null;
public $error = "";
function __construct () {
try {
$this->pdo = new PDO(
"mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=".DB_CHARSET,
DB_USER, DB_PASSWORD, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]);
} catch (Exception $ex) { exit($ex->getMessage()); }
}
// (B) DESTRUCTOR - CLOSE CONNECTION
function __destruct () {
if ($this->stmt !== null) { $this->stmt = null; }
if ($this->pdo !== null) { $this->pdo = null; }
}
// (C) EXECUTE SQL QUERY
function exec ($sql, $data=null) {
try {
$this->stmt = $this->pdo->prepare($sql);
$this->stmt->execute($data);
return true;
} catch (Exception $ex) {
$this->error = $ex->getMessage();
return false;
}
}
// (D) FETCH
function fetch ($sql, $data=null) {
if ($this->exec($sql, $data) === false) { return false; }
return $this->stmt->fetch();
}
}
- PAGE-bottom.php
</main>
</div>
</body>
</html>
- PAGE-top.php
<?php
// (A) LOGIN CHECK
$_ISADMIN = isset($_SESSION["user"]);
if (!$_ISADMIN && !isset($_ISLOGIN)) {
header("Location: ".URL_HOST."login.php"); exit();
}
if ($_ISADMIN && isset($_ISLOGIN)) {
header("Location: ".URL_HOST); exit();
} ?>
<!DOCTYPE html>
<html>
<head>
<title>ADMIN PANEL</title>
<meta name="robots" content="noindex, nofollow">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=2">
<link href="<?=URL_PUBLIC?>admin.css" rel="stylesheet">
<script>var url = {host:"<?=URL_HOST?>",public:"<?=URL_PUBLIC?>"};</script>
<script async src="<?=URL_PUBLIC?>admin.js"></script>
</head>
<body>
<!-- (B) NOW LOADING SPINNER -->
<div id="page-loader">
<img src="<?=URL_PUBLIC?>cube-loader.svg"/>
</div>
<?php if ($_ISADMIN) { ?>
<!-- (C) SIDE BAR -->
<nav id="page-sidebar">
<a href="<?=URL_HOST?>pageA.php">
<span class="ico">⚗</span> Module A
</a>
<a href="<?=URL_HOST?>pageB.php">
<span class="ico">⚘</span> Module B
</a>
</nav>
<?php } ?>
<!-- (D) MAIN CONTENTS -->
<div id="page-main">
<?php if ($_ISADMIN) { ?>
<!-- (D1) NAVIGATION BAR -->
<nav id="page-nav">
<div id="page-button-side" onclick="admin.sidebar();">☰</div>
<div id="page-button-out" onclick="admin.bye();">☓</div>
</nav>
<?php } ?>
<!-- (D2) PAGE CONTENTS -->
<main id="page-contents">
Now the ‘public’ directory turn..
- admin.css
/* (A) FONT & FORM */
* { font-family: Arial, sans-serif; }
h1, h2, h3, h4, h5, h6 { margin: 5px 0; }
button, input, textarea {
box-sizing: border-box; padding: 10px;
}
button, input[type=button], input[type=submit] {
color: #fff; background: #a92121;
border: 0; cursor: pointer;
}
/* (B) NOW LOADING */
#page-loader {
position: fixed; top: 0; left: 0; z-index: 999;
width: 100vw; height: 100vh;
background: rgba(0, 0, 0, 0.5);
display: flex; align-items: center; justify-content: center;
visibility: hidden; opacity: 0;
transition: opacity 0.2s;
}
#page-loader.active { visibility: visible; opacity: 1; }
/* (C) PAGE LAYOUT */
body {
padding: 0; margin: 0; display: flex;
align-items: stretch; min-height: 100vh;
}
#page-sidebar { width: 200px; }
#page-main { flex-grow: 1; }
/* (D) SIDEBAR */
/* (D1) SIDEBAR ITSELF */
#page-sidebar {
background: #353535;
transition: width 0.2s;
}
/* (D2) SIDEBAR ITEMS */
#page-sidebar a {
box-sizing: border-box; display: block;
width: 100%; padding: 10px;
color: #fff; text-decoration: none;
border-bottom: 1px solid #555;
}
#page-sidebar a:hover { background: #222; }
/* (D3) SIDEBAR ICONS */
#page-sidebar .ico {
display: inline-block; width:24px; text-align: center;
font-size: 20px; line-height: 20px; color: #f48042;
}
/* (D4) HIDE SIDEBAR ON SMALL SCREEN */
@media (max-width: 768px) {
#page-sidebar { width: 0; visibility: hidden; }
#page-sidebar.active { width: 200px; visibility: visible; }
}
/* (E) PAGE MAIN */
/* (E1) MAIN SECTION ITSELF */
#page-main { background: #f7f9fa; }
/* (E2) NAVIGATION BAR */
#page-nav {
position: relative; height: 50px;
color: #fff; background: #474747;
}
/* (E3) NAVIGATION BAR BUTTONS */
#page-button-side, #page-button-out {
position: absolute; top: 0;
width: 50px; height: 50px; line-height: 50px;
font-size: 28px; font-weight: bold; text-align: center;
background: #87260e; cursor: pointer;
}
#page-button-side { display: none; left: 0; }
#page-button-out { right: 0; }
@media (max-width: 768px) {
#page-button-side { display: block !important; }
}
/* (E4) CONTENTS */
#page-contents { padding: 20px; }
- admin.js
var admin = {
// (A) SHOW/HIDE "NOW LOADING" BLOCK
loading : (show) => {
var block = document.getElementById("page-loader");
if (show) { block.classList.add("active"); }
else { block.classList.remove("active"); }
},
// (B) TOGGLE SIDE BAR
sidebar : () => {
document.getElementById("page-sidebar").classList.toggle("active");
},
// (C) SIGN OFF
bye : () => { if (confirm("Sign off?")) {
admin.ajax({
url : url.host + "ajax-session.php",
data : { req : "out" },
ok : () => { location.reload(); }
});
}},
// (D) AJAX FETCH
// url : target url
// data : data to send
// ok : function to run on server "OK"
ajax : (opt) => {
// (D1) FORM DATA
let data = new FormData();
for (let [k, v] of Object.entries(opt.data)) { data.append(k, v); }
// (D2) FETCH
fetch(opt.url, { method:"POST", body:data })
.then((res) => {
if (res.status != 200) {
alert(`Server ${res.status} error`);
console.error(res);
} else { return res.text(); }
})
.then((txt) => {
if (txt != "OK") { alert(txt); }
else { opt.ok(); }
})
.catch((err) => { console.error(err); });
}
}
- cube-loader.svg
<svg width="100px" height="100px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" class="lds-cube" style="background: none;"><g transform="translate(25,25)"><rect ng-attr-x="{{config.dp}}" ng-attr-y="{{config.dp}}" ng-attr-width="{{config.blockSize}}" ng-attr-height="{{config.blockSize}}" ng-attr-fill="{{config.c1}}" x="-20" y="-20" width="40" height="40" fill="#fe0d02" transform="scale(1.3187 1.3187)"><animateTransform attributeName="transform" type="scale" calcMode="spline" values="1.5;1" keyTimes="0;1" dur="1s" keySplines="0 0.5 0.5 1" begin="-0.3s" repeatCount="indefinite"></animateTransform></rect></g><g transform="translate(75,25)"><rect ng-attr-x="{{config.dp}}" ng-attr-y="{{config.dp}}" ng-attr-width="{{config.blockSize}}" ng-attr-height="{{config.blockSize}}" ng-attr-fill="{{config.c2}}" x="-20" y="-20" width="40" height="40" fill="#feb200" transform="scale(1.00009 1.00009)"><animateTransform attributeName="transform" type="scale" calcMode="spline" values="1.5;1" keyTimes="0;1" dur="1s" keySplines="0 0.5 0.5 1" begin="-0.2s" repeatCount="indefinite"></animateTransform></rect></g><g transform="translate(25,75)"><rect ng-attr-x="{{config.dp}}" ng-attr-y="{{config.dp}}" ng-attr-width="{{config.blockSize}}" ng-attr-height="{{config.blockSize}}" ng-attr-fill="{{config.c3}}" x="-20" y="-20" width="40" height="40" fill="#043b42" transform="scale(1.01489 1.01489)"><animateTransform attributeName="transform" type="scale" calcMode="spline" values="1.5;1" keyTimes="0;1" dur="1s" keySplines="0 0.5 0.5 1" begin="0s" repeatCount="indefinite"></animateTransform></rect></g><g transform="translate(75,75)"><rect ng-attr-x="{{config.dp}}" ng-attr-y="{{config.dp}}" ng-attr-width="{{config.blockSize}}" ng-attr-height="{{config.blockSize}}" ng-attr-fill="{{config.c4}}" x="-20" y="-20" width="40" height="40" fill="#fe0d02" transform="scale(1.00442 1.00442)"><animateTransform attributeName="transform" type="scale" calcMode="spline" values="1.5;1" keyTimes="0;1" dur="1s" keySplines="0 0.5 0.5 1" begin="-0.1s" repeatCount="indefinite"></animateTransform></rect></g></svg>
At last you need to create a table in PHPMYSQL.
Here is SQL code.
-- (A) USERS TABLE
CREATE TABLE `users` (
`user_id` int(11) NOT NULL,
`user_email` varchar(255) NOT NULL,
`user_name` varchar(255) NOT NULL,
`user_password` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `users`
ADD PRIMARY KEY (`user_id`),
ADD UNIQUE KEY `user_email` (`user_email`),
ADD KEY `user_name` (`user_name`);
ALTER TABLE `users`
MODIFY `user_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1;
-- (B) DEFAULT USER
-- EMAIL: JOHN@DOE.COM | PASSWORD: 123456
INSERT INTO `users` (`user_id`, `user_email`, `user_name`, `user_password`) VALUES
(1, 'john@doe.com', 'John Doe', '$2y$10$vZJy7y4uqQQTRN3zdi2RE.5ZJJzGEEPnzEjFXm4nEOx023XQ2Qe..');
Login Credentials:
Username: john@doe.com & Password: 123456