first commit
This commit is contained in:
parent
3d6e640525
commit
939a90b84d
|
|
@ -0,0 +1,146 @@
|
||||||
|
<?php
|
||||||
|
if (session_status() === PHP_SESSION_NONE) {
|
||||||
|
session_start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!isset($_SESSION['login_user'])) {
|
||||||
|
header('Location: ./');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mendapatkan IDRFID dari sesi login
|
||||||
|
$rfid = $_SESSION['login_user'];
|
||||||
|
|
||||||
|
require_once("connectDB.php");
|
||||||
|
|
||||||
|
// Koneksi ke database
|
||||||
|
$conn = new mysqli($servername, $username, $password, $dbname);
|
||||||
|
|
||||||
|
// Check koneksi
|
||||||
|
if ($conn->connect_error) {
|
||||||
|
die("Koneksi gagal: " . $conn->connect_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query untuk mengambil data absensi sesuai dengan idrfid yang login
|
||||||
|
$sql = "SELECT * FROM data_absen WHERE idrfid = '$rfid' ORDER BY tgl DESC";
|
||||||
|
$result = $conn->query($sql);
|
||||||
|
|
||||||
|
// Menampilkan data absensi
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Dashboard - Cari RFID</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/userslog.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/font-awesome.min.css" />
|
||||||
|
<style>
|
||||||
|
/* Custom CSS untuk form */
|
||||||
|
.form-style-5 form input[type="text"],
|
||||||
|
.form-style-5 form input[type="date"],
|
||||||
|
.form-style-5 form button {
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
.form-style-5 form a#download_data {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #007bff;
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
margin-top: 10px; /* Tambah jarak antar tombol */
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src="js/jquery-2.2.3.min.js"></script>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function(){
|
||||||
|
$('#search_rfid').on('click', function(){
|
||||||
|
var rfid = $('#rfid_input').val();
|
||||||
|
var start_date = $('#start_date').val();
|
||||||
|
var end_date = $('#end_date').val();
|
||||||
|
|
||||||
|
if(rfid && start_date && end_date) {
|
||||||
|
$.ajax({
|
||||||
|
url: "cari_rfid_up.php",
|
||||||
|
type: 'POST',
|
||||||
|
data: {
|
||||||
|
'rfid': rfid,
|
||||||
|
'start_date': start_date,
|
||||||
|
'end_date': end_date
|
||||||
|
}
|
||||||
|
}).done(function(data) {
|
||||||
|
$('#rfid_result').html(data);
|
||||||
|
$('#hidden_rfid').val(rfid);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Tambahkan event listener ke download_data untuk menyertakan RFID dan tanggal dalam query string
|
||||||
|
$('#download_data').on('click', function() {
|
||||||
|
var rfid = $('#hidden_rfid').val();
|
||||||
|
var start_date = $('#start_date').val();
|
||||||
|
var end_date = $('#end_date').val();
|
||||||
|
|
||||||
|
if(rfid && start_date && end_date) {
|
||||||
|
window.location.href = 'excel.php?rfid=' + rfid + '&start_date=' + start_date + '&end_date=' + end_date;
|
||||||
|
} else {
|
||||||
|
alert("Cari RFID, Tanggal Awal, dan Tanggal Akhir terlebih dahulu");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<?php include 'header.php'; ?>
|
||||||
|
<header>
|
||||||
|
<nav>
|
||||||
|
<!-- <ul>
|
||||||
|
<li><a href="users_log.php">Dashboard</a></li>
|
||||||
|
<li><a href="cari_rfid.php">Cari RFID</a></li>
|
||||||
|
</ul> -->
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
<section>
|
||||||
|
<!-- Cari RFID -->
|
||||||
|
<h1 class="slideInDown animated">Cari RFID</h1>
|
||||||
|
<div class="form-style-5 slideInDown animated">
|
||||||
|
<form>
|
||||||
|
<input type="text" name="rfid_input" id="rfid_input" value="<?php echo $rfid; ?>" style="display: none;">
|
||||||
|
<input type="date" name="start_date" id="start_date" placeholder="Tanggal Awal">
|
||||||
|
<input type="date" name="end_date" id="end_date" placeholder="Tanggal Akhir">
|
||||||
|
<button type="button" id="search_rfid">Cari</button>
|
||||||
|
<input type="hidden" id="hidden_rfid" name="hidden_rfid">
|
||||||
|
<!-- <a href="#" id="download_data">Ambil Data</a> -->
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="tbl-header slideInRight animated">
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="text-center">Tanggal</th>
|
||||||
|
<th class="text-center">Rfid</th>
|
||||||
|
<th class="text-center">Waktu Masuk</th>
|
||||||
|
<th class="text-center">Photo Masuk</th>
|
||||||
|
<th class="text-center">Waktu Keluar</th>
|
||||||
|
<th class="text-center">Photo Keluar</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="tbl-content slideInRight animated">
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0">
|
||||||
|
<tbody id="rfid_result">
|
||||||
|
<!-- Hasil pencarian akan ditampilkan di sini -->
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
$target_dir = "images/photos/";
|
||||||
|
|
||||||
|
$datum = mktime(date('H')+0, date('i'), date('s'), date('m'), date('d'), date('y'));
|
||||||
|
$target_file = $target_dir . date('Y.m.d_H_i_s', $datum) . basename($_FILES["imageFile"]["name"]);
|
||||||
|
|
||||||
|
$target_dirs="uploads/";
|
||||||
|
$target_files = date('Y.m.d_H_i_s', $datum) . basename($_FILES["imageFile"]["name"]);
|
||||||
|
|
||||||
|
$uploadOk = 1;
|
||||||
|
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
|
||||||
|
|
||||||
|
// Check if image file is a actual image or fake image
|
||||||
|
if(isset($_POST["submit"])) {
|
||||||
|
$check = getimagesize($_FILES["imageFile"]["tmp_name"]);
|
||||||
|
if($check !== false) {
|
||||||
|
echo "File is an image - " . $check["mime"] . ".";
|
||||||
|
$uploadOk = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
echo "File is not an image.";
|
||||||
|
$uploadOk = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if file already exists
|
||||||
|
if (file_exists($target_file)) {
|
||||||
|
echo "Sorry, file already exists.";
|
||||||
|
$uploadOk = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check file size
|
||||||
|
if ($_FILES["imageFile"]["size"] > 500000) {
|
||||||
|
echo "Sorry, your file is too large.";
|
||||||
|
$uploadOk = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow certain file formats
|
||||||
|
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
|
||||||
|
&& $imageFileType != "gif" ) {
|
||||||
|
echo "Sorry, only JPG, JPEG, PNG & GIF files are allowed.";
|
||||||
|
$uploadOk = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if $uploadOk is set to 0 by an error
|
||||||
|
if ($uploadOk == 0) {
|
||||||
|
echo "Sorry, your file was not uploaded.";
|
||||||
|
// if everything is ok, try to upload file
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
|
||||||
|
$con = mysqli_connect("localhost","root","","labandroid_logabsencam");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$qry="SELECT * FROM data_absen WHERE status1=1 LIMIT 1";
|
||||||
|
$qry_ksr=mysqli_query($con,$qry);
|
||||||
|
$row_ksr=mysqli_fetch_array($qry_ksr);
|
||||||
|
$row_cnt = mysqli_num_rows($qry_ksr);
|
||||||
|
if($row_cnt){
|
||||||
|
$SQL="UPDATE data_absen SET gambar1 = '".$target_files."',status1=0 WHERE id = ".$row_ksr['id']."";
|
||||||
|
mysqli_query($con,$SQL);
|
||||||
|
}
|
||||||
|
|
||||||
|
$qry="SELECT * FROM data_absen WHERE status2=1 LIMIT 1";
|
||||||
|
$qry_ksr=mysqli_query($con,$qry);
|
||||||
|
$row_ksr=mysqli_fetch_array($qry_ksr);
|
||||||
|
$row_cnt = mysqli_num_rows($qry_ksr);
|
||||||
|
if($row_cnt){
|
||||||
|
$SQL="UPDATE data_absen SET gambar2 = '".$target_files."',status2=0 WHERE id = ".$row_ksr['id']."";
|
||||||
|
mysqli_query($con,$SQL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (move_uploaded_file($_FILES["imageFile"]["tmp_name"], $target_file)) {
|
||||||
|
echo "The file ". basename( $_FILES["imageFile"]["name"]). " has been uploaded.";
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
echo "Sorry, there was an error uploading your file.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
@ -0,0 +1,243 @@
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESP8266HTTPClient.h>
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <MFRC522.h>
|
||||||
|
#include <Adafruit_GFX.h>
|
||||||
|
#include <Adafruit_SSD1306.h>
|
||||||
|
#include <ArduinoJson.h>AllTopic:All
|
||||||
|
#include "icon.h"
|
||||||
|
#include <UniversalTelegramBot.h> // tambahkan include untuk library Telegram
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
// Inisialisasi OLED
|
||||||
|
#define SCREEN_WIDTH 128
|
||||||
|
#define SCREEN_HEIGHT 64
|
||||||
|
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);
|
||||||
|
|
||||||
|
#define RST_PIN 16 // pin-D0
|
||||||
|
#define SS_PIN 0 // pin-D3
|
||||||
|
byte buzzer = 15; // pin D8
|
||||||
|
MFRC522 mfrc522(SS_PIN, RST_PIN); // Buat instance MFRC522
|
||||||
|
|
||||||
|
const char *ssid = "Iphone"; // SSID WiFi Anda
|
||||||
|
const char *password = "44444444"; // Kata sandi WiFi Anda
|
||||||
|
String server_addr = "192.168.107.197"; // Alamat server atau IP komputer Anda
|
||||||
|
|
||||||
|
byte readCard[4];
|
||||||
|
uint8_t successRead;
|
||||||
|
String UIDCard;
|
||||||
|
|
||||||
|
#define BOT_TOKEN "6508339619:AAGeFNlU5M7uwpiImHHi88M6HGCxjVrob58" // Ganti dengan token bot Anda
|
||||||
|
WiFiClient client;
|
||||||
|
UniversalTelegramBot bot(BOT_TOKEN, client);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
pinMode(buzzer, OUTPUT);
|
||||||
|
Serial.begin(9600); // Inisialisasi komunikasi serial dengan PC
|
||||||
|
SPI.begin(); // Inisialisasi bus SPI
|
||||||
|
mfrc522.PCD_Init(); // Inisialisasi kartu MFRC522
|
||||||
|
Serial.println(F("Read Uid data on a MIFARE PICC:"));
|
||||||
|
ShowReaderDetails(); // Tampilkan detail pembaca kartu MFRC522
|
||||||
|
|
||||||
|
// Inisialisasi koneksi WiFi dan OLED
|
||||||
|
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
|
||||||
|
Serial.println(F("SSD1306 allocation failed"));
|
||||||
|
for (;;)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
display.clearDisplay();
|
||||||
|
display.setTextColor(WHITE);
|
||||||
|
display.setTextSize(1);
|
||||||
|
display.setCursor(38, 20);
|
||||||
|
display.println(F("ARDUCODING"));
|
||||||
|
display.setCursor(35, 35);
|
||||||
|
display.println(F("Mesin Absen"));
|
||||||
|
display.display();
|
||||||
|
delay(1000);
|
||||||
|
ConnectWIFI();
|
||||||
|
delay(2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
display.clearDisplay();
|
||||||
|
display.drawBitmap(32, 0, cardBitmap, 68, 50, WHITE);
|
||||||
|
display.setTextSize(1);
|
||||||
|
display.setCursor(30, 55);
|
||||||
|
display.print("Tap Your Card!");
|
||||||
|
display.display();
|
||||||
|
successRead = getID();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t getID() {
|
||||||
|
if (!mfrc522.PICC_IsNewCardPresent()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!mfrc522.PICC_ReadCardSerial()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
UIDCard = "";
|
||||||
|
Serial.println(F("Scanned PICC's UID:"));
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < mfrc522.uid.size; i++) {
|
||||||
|
UIDCard += String(mfrc522.uid.uidByte[i], HEX);
|
||||||
|
}
|
||||||
|
UIDCard.toUpperCase();
|
||||||
|
Serial.print("UID:");
|
||||||
|
Serial.println(UIDCard);
|
||||||
|
Serial.println(F("**End Reading**"));
|
||||||
|
digitalWrite(buzzer, HIGH);
|
||||||
|
delay(200);
|
||||||
|
digitalWrite(buzzer, LOW);
|
||||||
|
delay(200);
|
||||||
|
digitalWrite(buzzer, HIGH);
|
||||||
|
delay(200);
|
||||||
|
digitalWrite(buzzer, LOW);
|
||||||
|
|
||||||
|
storeData();
|
||||||
|
delay(2000);
|
||||||
|
|
||||||
|
mfrc522.PICC_HaltA();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void storeData() {
|
||||||
|
ConnectWIFI();
|
||||||
|
WiFiClient client;
|
||||||
|
String address, massage, first_name;
|
||||||
|
|
||||||
|
address = "http://" + server_addr + "/absensi/webapi/api/create.php?uid=" + UIDCard;
|
||||||
|
|
||||||
|
HTTPClient http;
|
||||||
|
http.begin(client, address);
|
||||||
|
int httpCode = http.GET();
|
||||||
|
String payload;
|
||||||
|
Serial.print("Response: ");
|
||||||
|
if (httpCode > 0) {
|
||||||
|
payload = http.getString();
|
||||||
|
payload.trim();
|
||||||
|
if (payload.length() > 0) {
|
||||||
|
Serial.println(payload + "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
http.end();
|
||||||
|
|
||||||
|
const size_t capacity = JSON_OBJECT_SIZE(4) + 70;
|
||||||
|
DynamicJsonDocument doc(capacity);
|
||||||
|
|
||||||
|
DeserializationError error = deserializeJson(doc, payload);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
Serial.print(F("deserializeJson() failed: "));
|
||||||
|
Serial.println(error.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *waktu_res = doc["waktu"];
|
||||||
|
String nama_res = doc["nama"];
|
||||||
|
const char *uid_res = doc["uid"];
|
||||||
|
String status_res = doc["status"];
|
||||||
|
|
||||||
|
for (int i = 0; i < nama_res.length(); i++) {
|
||||||
|
if (nama_res.charAt(i) == ' ') {
|
||||||
|
first_name = nama_res.substring(0, i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kirim notifikasi Telegram
|
||||||
|
sendTelegramNotification(status_res, first_name, waktu_res, uid_res);
|
||||||
|
|
||||||
|
display.clearDisplay();
|
||||||
|
display.drawBitmap(0, 5, userBitmap, 50, 60, WHITE);
|
||||||
|
display.setTextColor(WHITE);
|
||||||
|
display.setTextSize(1);
|
||||||
|
|
||||||
|
if (status_res == "INVALID") {
|
||||||
|
massage = "Who are you?";
|
||||||
|
display.setCursor(52, 15);
|
||||||
|
display.print(massage);
|
||||||
|
display.setCursor(52, 30);
|
||||||
|
display.print(uid_res);
|
||||||
|
display.setCursor(52, 40);
|
||||||
|
display.print(status_res);
|
||||||
|
} else {
|
||||||
|
if (status_res == "IN") {
|
||||||
|
massage = "Welcome!";
|
||||||
|
} else {
|
||||||
|
massage = "See you!";
|
||||||
|
}
|
||||||
|
display.setCursor(52, 15);
|
||||||
|
display.print(massage);
|
||||||
|
display.setCursor(52, 30);
|
||||||
|
display.print(first_name);
|
||||||
|
display.setCursor(52, 40);
|
||||||
|
display.print(waktu_res);
|
||||||
|
}
|
||||||
|
display.display();
|
||||||
|
delay(3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendTelegramNotification(String status, String first_name, const char *waktu, const char *uid) {
|
||||||
|
String message = "Kartu dengan UID " + String(uid) + " telah " + (status == "IN" ? "masuk" : "keluar") + ".";
|
||||||
|
bot.sendMessage("1263710714", message); // Ganti "chat_id" dengan ID obrolan Anda
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConnectWIFI() {
|
||||||
|
if (WiFi.status() != WL_CONNECTED) {
|
||||||
|
Serial.print("Attempting to connect to SSID: ");
|
||||||
|
Serial.println(ssid);
|
||||||
|
WiFi.begin(ssid, password);
|
||||||
|
int i = 0;
|
||||||
|
int a = 0;
|
||||||
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
|
Serial.print(".");
|
||||||
|
display.clearDisplay();
|
||||||
|
display.setTextSize(1);
|
||||||
|
if (a == 0) {
|
||||||
|
display.drawBitmap(52, 20, wifi_icon, 16, 16, WHITE);
|
||||||
|
a = 1;
|
||||||
|
} else {
|
||||||
|
display.drawBitmap(52, 20, wifi_icon, 16, 16, BLACK);
|
||||||
|
a = 0;
|
||||||
|
}
|
||||||
|
display.setCursor(25, 50);
|
||||||
|
display.print("Connecting ...");
|
||||||
|
display.display();
|
||||||
|
delay(1000);
|
||||||
|
++i;
|
||||||
|
if (i == 30) {
|
||||||
|
i = 0;
|
||||||
|
Serial.println("\n Failed to Connect.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Serial.println("\n Connected!");
|
||||||
|
display.clearDisplay();
|
||||||
|
display.setTextSize(1);
|
||||||
|
display.drawBitmap(52, 20, wifi_icon, 16, 16, WHITE);
|
||||||
|
display.setCursor(33, 50);
|
||||||
|
display.print("Connected!");
|
||||||
|
display.display();
|
||||||
|
delay(2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShowReaderDetails() {
|
||||||
|
byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
|
||||||
|
Serial.print(F("MFRC522 Software Version: 0x"));
|
||||||
|
Serial.print(v, HEX);
|
||||||
|
if (v == 0x91)
|
||||||
|
Serial.print(F(" = v1.0"));
|
||||||
|
else if (v == 0x92)
|
||||||
|
Serial.print(F(" = v2.0"));
|
||||||
|
else
|
||||||
|
Serial.print(F(" (unknown),probably a chinese clone?"));
|
||||||
|
Serial.println("");
|
||||||
|
|
||||||
|
if ((v == 0x00) || (v == 0xFF)) {
|
||||||
|
Serial.println(F("WARNING: Communication failure, is the MFRC522 properly connected?"));
|
||||||
|
Serial.println(F("SYSTEM HALTED: Check connections."));
|
||||||
|
while (true)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
// 'wifi-icon', 16x16px
|
||||||
|
const unsigned char wifi_icon [] PROGMEM = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x1f, 0xf8, 0x7c, 0x3e, 0xe7, 0xe7, 0xdf, 0xfb, 0x39, 0x1c,
|
||||||
|
0x37, 0xec, 0x0f, 0xf0, 0x0f, 0xf0, 0x03, 0xc0, 0x03, 0xc0, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
// 'user_white', 50x60px
|
||||||
|
const unsigned char userBitmap [] PROGMEM = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf0,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xfe, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x07, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00,
|
||||||
|
0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x1f, 0xff,
|
||||||
|
0xff, 0xf8, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xfc, 0xf8, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xf8, 0xf8,
|
||||||
|
0x00, 0x00, 0x00, 0x3f, 0xff, 0xe0, 0xf8, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x81, 0xf8, 0x00, 0x00,
|
||||||
|
0x00, 0x0f, 0xf0, 0x01, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x38, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x38, 0x00,
|
||||||
|
0x00, 0x00, 0x07, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
|
||||||
|
0x07, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x78, 0x00, 0x00, 0x00, 0x03, 0x80,
|
||||||
|
0x00, 0xf0, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x03, 0xe0,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x3f, 0x80, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x3f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x80, 0x00,
|
||||||
|
0x00, 0x00, 0x01, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x03, 0xf8, 0x00, 0x00, 0x00,
|
||||||
|
0x1f, 0x80, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x7c, 0x00,
|
||||||
|
0x00, 0x0f, 0x80, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x03,
|
||||||
|
0xe0, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0xf0, 0x00,
|
||||||
|
0x03, 0x80, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
// 'Card_icon', 68x50px
|
||||||
|
const unsigned char cardBitmap [] PROGMEM = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||||
|
0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x0f, 0xff, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0xff, 0xf0, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x1c, 0x00, 0x00,
|
||||||
|
0x00, 0x07, 0xff, 0xc0, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x0c,
|
||||||
|
0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x07, 0xff, 0xc0, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x0c, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x38, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x06, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x06, 0x00, 0x60, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x0f, 0xf0, 0x06, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x06, 0x00,
|
||||||
|
0x60, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x06, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x9c,
|
||||||
|
0x07, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x38, 0x0e, 0x07, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x38, 0x4e, 0x03, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x38, 0x0e, 0x03, 0x00, 0x30, 0x00, 0x20,
|
||||||
|
0x00, 0x00, 0x38, 0x0e, 0x03, 0x00, 0x30, 0x07, 0xf0, 0x00, 0x00, 0x38, 0x0e, 0x03, 0x00, 0x38,
|
||||||
|
0x1f, 0xf0, 0x00, 0x00, 0x3c, 0x1e, 0x03, 0x80, 0x18, 0x1f, 0xf0, 0x00, 0x00, 0x3e, 0x1e, 0x01,
|
||||||
|
0x80, 0x18, 0x1f, 0xf0, 0x00, 0x00, 0x1f, 0x01, 0x01, 0x80, 0x18, 0x1f, 0xf8, 0x00, 0x00, 0x1c,
|
||||||
|
0x01, 0xc1, 0x80, 0x18, 0x1f, 0xf8, 0x00, 0x00, 0x10, 0x03, 0xc1, 0x80, 0x18, 0x0f, 0xf8, 0x00,
|
||||||
|
0x00, 0x38, 0x07, 0xc1, 0xc0, 0x0c, 0x0f, 0xc0, 0x00, 0x00, 0x3c, 0x1f, 0xc0, 0xc0, 0x0c, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x3f, 0xff, 0x00, 0xc0, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0xc0,
|
||||||
|
0x0c, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xc0, 0x0c, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00,
|
||||||
|
0x00, 0xe0, 0x0e, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x00, 0x00, 0xe0, 0x06, 0x00, 0x3f, 0xfc, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0xe0, 0x06, 0x03, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x06, 0x03, 0xc0,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x07,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfe, 0x00,
|
||||||
|
0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xff, 0xf8,
|
||||||
|
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x07, 0xff,
|
||||||
|
0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff,
|
||||||
|
0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
// Sertakan file konfigurasi
|
||||||
|
require_once "config.php";
|
||||||
|
|
||||||
|
if(isset($_POST["idrfid"])){
|
||||||
|
$sql = "SELECT * FROM data_registrasi WHERE idrfid = ?";
|
||||||
|
|
||||||
|
if($stmt = mysqli_prepare($link, $sql)){
|
||||||
|
mysqli_stmt_bind_param($stmt, "s", $param_idrfid);
|
||||||
|
$param_idrfid = trim($_POST["idrfid"]);
|
||||||
|
|
||||||
|
if(mysqli_stmt_execute($stmt)){
|
||||||
|
mysqli_stmt_store_result($stmt);
|
||||||
|
|
||||||
|
if(mysqli_stmt_num_rows($stmt) > 0){
|
||||||
|
echo '1';
|
||||||
|
} else {
|
||||||
|
echo '0';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo '0';
|
||||||
|
}
|
||||||
|
mysqli_stmt_close($stmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mysqli_close($link);
|
||||||
|
?>
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
$link = mysqli_connect("localhost", "root", "", "labandroid_logabsencam");
|
||||||
|
$db_server = "localhost";
|
||||||
|
$db_name = "labandroid_logabsencam";
|
||||||
|
$db_user = "root";
|
||||||
|
$db_password = "";
|
||||||
|
|
||||||
|
$conn = mysqli_connect($db_server, $db_user, $db_password, $db_name);
|
||||||
|
|
||||||
|
if ($conn->connect_error) {
|
||||||
|
die("Database Connection failed: " . $conn->connect_error);
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
<?php require 'config.php'; ?>
|
||||||
|
<table border="1" cellpadding="10" cellspacing="5">
|
||||||
|
<tr>
|
||||||
|
<td>#</td>
|
||||||
|
<td>created</td>
|
||||||
|
<td>idrfid</td>
|
||||||
|
<td>nama</td>
|
||||||
|
<td>division</td>
|
||||||
|
<td>mail</td>
|
||||||
|
<td>alamat</td>
|
||||||
|
<td>tgl</td>
|
||||||
|
<td>jam masuk</td>
|
||||||
|
<td>jam keluar</td>
|
||||||
|
<td>Action</td>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
$i = 1;
|
||||||
|
$query = "SELECT k.*, a.tgl, a.rekap_masuk, a.rekap_keluar,
|
||||||
|
CASE
|
||||||
|
WHEN a.rekap_masuk > '09:00:00' AND a.rekap_keluar < '16:00:00' THEN 'Terlambat dan Pulang Dulu'
|
||||||
|
WHEN a.rekap_masuk > '09:00:00' THEN 'Terlambat'
|
||||||
|
WHEN a.rekap_keluar < '16:00:00' THEN 'Pulang Dulu'
|
||||||
|
ELSE 'Tidak Terlambat'
|
||||||
|
END AS action
|
||||||
|
FROM data_karyawan k
|
||||||
|
INNER JOIN data_absen a ON k.idrfid = a.idrfid
|
||||||
|
ORDER BY k.nama";
|
||||||
|
|
||||||
|
$rows = mysqli_query($conn, $query);
|
||||||
|
foreach($rows as $row) :
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td> <?php echo $i++; ?> </td>
|
||||||
|
<td> <?php echo $row["created"]; ?> </td>
|
||||||
|
<td> <?php echo $row["idrfid"]; ?> </td>
|
||||||
|
<td> <?php echo $row["nama"]; ?> </td>
|
||||||
|
<td> <?php echo $row["division"]; ?> </td>
|
||||||
|
<td> <?php echo $row["mail"]; ?> </td>
|
||||||
|
<td> <?php echo $row["alamat"]; ?> </td>
|
||||||
|
<td> <?php echo $row["tgl"]; ?> </td>
|
||||||
|
<td> <?php echo $row["rekap_masuk"]; ?> </td>
|
||||||
|
<td> <?php echo $row["rekap_keluar"]; ?> </td>
|
||||||
|
<td> <?php echo $row["action"]; ?> </td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
<table border="1" cellpadding="10" cellspacing="5">
|
||||||
|
<tr>
|
||||||
|
<td>Nama</td>
|
||||||
|
<td>Tidak Terlambat</td>
|
||||||
|
<td>Terlambat</td>
|
||||||
|
<td>Pulang Dulu</td>
|
||||||
|
<td>Terlambat dan Pulang Dulu</td>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
$query_rekap = "SELECT k.nama,
|
||||||
|
SUM(CASE WHEN a.rekap_masuk <= '09:00:00' AND a.rekap_keluar >= '16:00:00' THEN 1 ELSE 0 END) AS tidak_terlambat,
|
||||||
|
SUM(CASE WHEN a.rekap_masuk > '09:00:00' THEN 1 ELSE 0 END) AS terlambat,
|
||||||
|
SUM(CASE WHEN a.rekap_keluar < '16:00:00' THEN 1 ELSE 0 END) AS pulang_dulu,
|
||||||
|
SUM(CASE WHEN a.rekap_masuk > '09:00:00' AND a.rekap_keluar < '16:00:00' THEN 1 ELSE 0 END) AS terlambat_dan_pulang_dulu
|
||||||
|
FROM data_karyawan k
|
||||||
|
INNER JOIN data_absen a ON k.idrfid = a.idrfid
|
||||||
|
GROUP BY k.nama
|
||||||
|
ORDER BY k.nama";
|
||||||
|
|
||||||
|
$rows_rekap = mysqli_query($conn, $query_rekap);
|
||||||
|
foreach($rows_rekap as $row_rekap) :
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td> <?php echo $row_rekap["nama"]; ?> </td>
|
||||||
|
<td> <?php echo $row_rekap["tidak_terlambat"]; ?> </td>
|
||||||
|
<td> <?php echo $row_rekap["terlambat"]; ?> </td>
|
||||||
|
<td> <?php echo $row_rekap["pulang_dulu"]; ?> </td>
|
||||||
|
<td> <?php echo $row_rekap["terlambat_dan_pulang_dulu"]; ?> </td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</table>
|
||||||
|
|
@ -0,0 +1,317 @@
|
||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
if (!isset($_SESSION['login_admin'])) {
|
||||||
|
header('Location: http://localhost/rfidcam/'); // Redirect ke halaman login jika bukan admin
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="id">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
<title>Dashboard R-collection</title>
|
||||||
|
<link href="../src/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i"
|
||||||
|
rel="stylesheet">
|
||||||
|
<link href="../src/css/sb-admin-2.min.css" rel="stylesheet">
|
||||||
|
<link href="../src/vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||||
|
<script src="../src/vendor/jquery/jquery.min.js"></script>
|
||||||
|
<script src="../src/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(document).ready(function () {
|
||||||
|
// Fungsi untuk mengambil dan memperbarui tabel
|
||||||
|
function fetchAndUpdateTable(query = '') {
|
||||||
|
$.ajax({
|
||||||
|
url: 'data_absen_ajax.php',
|
||||||
|
method: 'GET',
|
||||||
|
data: {search: query},
|
||||||
|
dataType: 'json',
|
||||||
|
success: function (data) {
|
||||||
|
let tableBody = '';
|
||||||
|
data.forEach(row => {
|
||||||
|
tableBody += `<tr>
|
||||||
|
<td>${row.tgl}</td>
|
||||||
|
<td>${row.idrfid}</td>
|
||||||
|
<td>${row.nama}</td>
|
||||||
|
<td class='jam-masuk'>${row.jam_masuk}</td>
|
||||||
|
<td class='jam-keluar'>${row.jam_keluar}</td>
|
||||||
|
<td class='action-cell'></td>
|
||||||
|
</tr>`;
|
||||||
|
});
|
||||||
|
$('tbody').html(tableBody);
|
||||||
|
highlightLateTimes(); // Sorot setelah mengambil data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event listener untuk input pencarian saat menekan tombol Enter
|
||||||
|
$('#searchInput').on('keyup', function () {
|
||||||
|
let searchQuery = this.value.trim();
|
||||||
|
fetchAndUpdateTable(searchQuery);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fungsi untuk menyoroti waktu yang terlambat
|
||||||
|
function highlightLateTimes() {
|
||||||
|
let jamMasukLimit = localStorage.getItem('jamMasukLimit') || '09:00';
|
||||||
|
let jamKeluarLimit = localStorage.getItem('jamKeluarLimit') || '16:00';
|
||||||
|
|
||||||
|
document.querySelectorAll('.jam-masuk').forEach(function (element) {
|
||||||
|
if (element.textContent > jamMasukLimit) {
|
||||||
|
element.style.color = 'red';
|
||||||
|
} else {
|
||||||
|
element.style.color = 'black';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.querySelectorAll('.jam-keluar').forEach(function (element) {
|
||||||
|
if (element.textContent < jamKeluarLimit) {
|
||||||
|
element.style.color = 'red';
|
||||||
|
} else {
|
||||||
|
element.style.color = 'black';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.querySelectorAll('tr').forEach(function (row) {
|
||||||
|
let jamMasuk = row.querySelector('.jam-masuk');
|
||||||
|
let jamKeluar = row.querySelector('.jam-keluar');
|
||||||
|
let actionCell = row.querySelector('.action-cell');
|
||||||
|
|
||||||
|
if (jamMasuk && jamKeluar && actionCell) {
|
||||||
|
let terlambat = jamMasuk.style.color === 'red';
|
||||||
|
let pulangDulu = jamKeluar.style.color === 'red';
|
||||||
|
|
||||||
|
if (terlambat && pulangDulu) {
|
||||||
|
actionCell.textContent = 'Terlambat dan Pulang Dulu';
|
||||||
|
} else if (terlambat) {
|
||||||
|
actionCell.textContent = 'Terlambat';
|
||||||
|
} else if (pulangDulu) {
|
||||||
|
actionCell.textContent = 'Pulang Dulu';
|
||||||
|
} else {
|
||||||
|
actionCell.textContent = 'Tidak Terlambat';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event listener untuk tombol atur batas jam
|
||||||
|
$('#setLimitBtn').on('click', function () {
|
||||||
|
let jamMasukLimit = document.getElementById('jamMasukLimit').value;
|
||||||
|
let jamKeluarLimit = document.getElementById('jamKeluarLimit').value;
|
||||||
|
|
||||||
|
localStorage.setItem('jamMasukLimit', jamMasukLimit);
|
||||||
|
localStorage.setItem('jamKeluarLimit', jamKeluarLimit);
|
||||||
|
|
||||||
|
highlightLateTimes();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set nilai batas jam dari Local Storage saat halaman dimuat
|
||||||
|
if (localStorage.getItem('jamMasukLimit')) {
|
||||||
|
document.getElementById('jamMasukLimit').value = localStorage.getItem('jamMasukLimit');
|
||||||
|
}
|
||||||
|
if (localStorage.getItem('jamKeluarLimit')) {
|
||||||
|
document.getElementById('jamKeluarLimit').value = localStorage.getItem('jamKeluarLimit');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Panggil fungsi untuk pertama kali untuk menampilkan data awal
|
||||||
|
fetchAndUpdateTable();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body id="page-top">
|
||||||
|
<!-- Page Wrapper -->
|
||||||
|
<div id="wrapper">
|
||||||
|
<!-- Sidebar -->
|
||||||
|
<?php include 'partial_sidebar.php'; ?>
|
||||||
|
<!-- End of Sidebar -->
|
||||||
|
|
||||||
|
<!-- Content Wrapper -->
|
||||||
|
<div id="content-wrapper" class="d-flex flex-column">
|
||||||
|
<!-- Main Content -->
|
||||||
|
<div id="content">
|
||||||
|
<!-- Topbar -->
|
||||||
|
<?php include 'partial_topbar.php'; ?>
|
||||||
|
<!-- End of Topbar -->
|
||||||
|
|
||||||
|
<!-- Begin Page Content -->
|
||||||
|
<div class="container-fluid">
|
||||||
|
<!-- Page Heading -->
|
||||||
|
<h1 class="h3 mb-2 text-gray-800">Data Absensi</h1>
|
||||||
|
<!-- DataTales Example -->
|
||||||
|
<div class="card shadow mb-4">
|
||||||
|
<div class="card-header py-3">
|
||||||
|
<h6 class="m-0 font-weight-bold text-primary">Data Absensi Harian</h6>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<form action="data_absen-index.php" method="get">
|
||||||
|
<div class="col">
|
||||||
|
<input type="text" class="form-control" placeholder="Pencarian data karyawan" name="search" id="searchInput">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<!-- Form untuk mengatur waktu masuk dan keluar -->
|
||||||
|
<div class="row mb-4 justify-content-center">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label for="jamMasukLimit">Jam Masuk Batas:</label>
|
||||||
|
<input type="time" id="jamMasukLimit" class="form-control" value="09:00">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label for="jamKeluarLimit">Jam Keluar Batas:</label>
|
||||||
|
<input type="time" id="jamKeluarLimit" class="form-control" value="16:00">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<button id="setLimitBtn" class="btn btn-primary mb-4">Atur Batas Jam</button>
|
||||||
|
</div>
|
||||||
|
<!-- Sisa kode Anda -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
require_once "config.php";
|
||||||
|
|
||||||
|
if (isset($_GET['pageno'])) {
|
||||||
|
$pageno = $_GET['pageno'];
|
||||||
|
} else {
|
||||||
|
$pageno = 1;
|
||||||
|
}
|
||||||
|
$no_of_records_per_page = 10;
|
||||||
|
$offset = ($pageno - 1) * $no_of_records_per_page;
|
||||||
|
|
||||||
|
$total_pages_sql = "SELECT COUNT(*) FROM data_absen";
|
||||||
|
$result = mysqli_query($link, $total_pages_sql);
|
||||||
|
$total_rows = mysqli_fetch_array($result)[0];
|
||||||
|
$total_pages = ceil($total_rows / $no_of_records_per_page);
|
||||||
|
|
||||||
|
$orderBy = array('tgl', 'idrfid', 'nama');
|
||||||
|
$order = 'tgl'; // Ubah order menjadi 'tgl' untuk mengambil data berdasarkan tanggal absensi
|
||||||
|
$sort = 'desc';
|
||||||
|
if (isset($_GET['order']) && in_array($_GET['order'], $orderBy)) {
|
||||||
|
$order = $_GET['order'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$sortBy = array('asc', 'desc');
|
||||||
|
$sort = 'desc';
|
||||||
|
if (isset($_GET['sort']) && in_array($_GET['sort'], $sortBy)) {
|
||||||
|
if ($_GET['sort'] == 'asc') {
|
||||||
|
$sort = 'desc';
|
||||||
|
} else {
|
||||||
|
$sort = 'asc';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "SELECT data_absen.idrfid, tgl, nama, division,
|
||||||
|
rekap_masuk AS jam_masuk,
|
||||||
|
rekap_keluar AS jam_keluar
|
||||||
|
FROM data_absen
|
||||||
|
JOIN data_karyawan ON data_absen.idrfid=data_karyawan.idrfid";
|
||||||
|
if (!empty($searchQuery)) {
|
||||||
|
$sql .= " WHERE tgl LIKE '%$searchQuery%' OR data_absen.idrfid LIKE '%$searchQuery%' OR nama LIKE '%$searchQuery%'";
|
||||||
|
}
|
||||||
|
$sql .= " ORDER BY $order $sort LIMIT $offset, $no_of_records_per_page";
|
||||||
|
|
||||||
|
$result = mysqli_query($link, $sql);
|
||||||
|
?>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th><a href="?search=<?php echo $searchQuery; ?>&sort=<?php echo $sort ?>&order=tgl">Tanggal</a></th>
|
||||||
|
<th><a href="?search=<?php echo $searchQuery; ?>&sort=<?php echo $sort ?>&order=idrfid">ID RFID</a></th>
|
||||||
|
<th><a href="?search=<?php echo $searchQuery; ?>&sort=<?php echo $sort ?>&order=nama">Nama</a></th>
|
||||||
|
<th>Jam Masuk</th>
|
||||||
|
<th>Jam Keluar</th>
|
||||||
|
<th>Status</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php
|
||||||
|
while ($row = mysqli_fetch_assoc($result)) {
|
||||||
|
echo "<tr>";
|
||||||
|
echo "<td>" . $row['tgl'] . "</td>";
|
||||||
|
echo "<td>" . $row['idrfid'] . "</td>";
|
||||||
|
echo "<td>" . $row['nama'] . "</td>";
|
||||||
|
echo "<td class='jam-masuk'>" . $row['jam_masuk'] . "</td>";
|
||||||
|
echo "<td class='jam-keluar'>" . $row['jam_keluar'] . "</td>";
|
||||||
|
echo "<td class='action-cell'></td>";
|
||||||
|
echo "</tr>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<nav aria-label="Page navigation example">
|
||||||
|
<ul class="pagination">
|
||||||
|
<li class="page-item"><a class="page-link" href="?pageno=1">First</a></li>
|
||||||
|
<li class="page-item <?php if($pageno <= 1){ echo 'disabled'; } ?>">
|
||||||
|
<a class="page-link" href="<?php if($pageno <= 1){ echo '#'; } else { echo "?pageno=".($pageno - 1); } ?>">Prev</a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item <?php if($pageno >= $total_pages){ echo 'disabled'; } ?>">
|
||||||
|
<a class="page-link" href="<?php if($pageno >= $total_pages){ echo '#'; } else { echo "?pageno=".($pageno + 1); } ?>">Next</a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item"><a class="page-link" href="?pageno=<?php echo $total_pages; ?>">Last</a></li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<?php
|
||||||
|
mysqli_free_result($result);
|
||||||
|
mysqli_close($link);
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /.container-fluid -->
|
||||||
|
</div>
|
||||||
|
<!-- End of Main Content -->
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<footer class="sticky-footer bg-white">
|
||||||
|
<div class="container my-auto">
|
||||||
|
<div class="copyright text-center my-auto">
|
||||||
|
<span>Copyright © Your Website 2024</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
<!-- End of Footer -->
|
||||||
|
</div>
|
||||||
|
<!-- End of Content Wrapper -->
|
||||||
|
</div>
|
||||||
|
<!-- End of Page Wrapper -->
|
||||||
|
|
||||||
|
<!-- Scroll to Top Button-->
|
||||||
|
<a class="scroll-to-top rounded" href="#page-top">
|
||||||
|
<i class="fas fa-angle-up"></i>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- Logout Modal-->
|
||||||
|
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
|
||||||
|
aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="exampleModalLabel">Ready to Leave?</h5>
|
||||||
|
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">Select "Logout" below if you are ready to end your current session.</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||||
|
<a class="btn btn-primary" href="login.html">Logout</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="../src/vendor/jquery-easing/jquery.easing.min.js"></script>
|
||||||
|
<script src="../src/js/sb-admin-2.min.js"></script>
|
||||||
|
<script src="../src/vendor/datatables/jquery.dataTables.min.js"></script>
|
||||||
|
<script src="../src/vendor/datatables/dataTables.bootstrap4.min.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
require_once "config.php";
|
||||||
|
|
||||||
|
$searchQuery = isset($_GET['search']) ? $_GET['search'] : ''; // Ambil parameter pencarian
|
||||||
|
|
||||||
|
$order = 'tgl'; // Ubah order menjadi 'tgl' untuk mengambil data berdasarkan tanggal absensi
|
||||||
|
$sort = 'desc';
|
||||||
|
|
||||||
|
// Query SQL dengan tambahan pencarian
|
||||||
|
$sql = "SELECT data_absen.idrfid, tgl, nama, division,
|
||||||
|
rekap_masuk AS jam_masuk,
|
||||||
|
rekap_keluar AS jam_keluar
|
||||||
|
FROM data_absen
|
||||||
|
JOIN data_karyawan ON data_absen.idrfid=data_karyawan.idrfid";
|
||||||
|
|
||||||
|
if (!empty($searchQuery)) {
|
||||||
|
$sql .= " WHERE tgl LIKE '%$searchQuery%' OR data_absen.idrfid LIKE '%$searchQuery%' OR nama LIKE '%$searchQuery%'";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ubah urutan berdasarkan tanggal terbaru
|
||||||
|
$sql .= " ORDER BY $order $sort";
|
||||||
|
|
||||||
|
$result = mysqli_query($link, $sql);
|
||||||
|
$data = array();
|
||||||
|
while ($row = mysqli_fetch_assoc($result)) {
|
||||||
|
$data[] = $row;
|
||||||
|
}
|
||||||
|
mysqli_free_result($result);
|
||||||
|
mysqli_close($link);
|
||||||
|
|
||||||
|
// Kembalikan data dalam format JSON
|
||||||
|
echo json_encode($data);
|
||||||
|
?>
|
||||||
|
|
@ -0,0 +1,250 @@
|
||||||
|
<?php
|
||||||
|
date_default_timezone_set('Asia/Jakarta');
|
||||||
|
// Include config file
|
||||||
|
require_once "config.php";
|
||||||
|
|
||||||
|
// Define variables and initialize with empty values
|
||||||
|
$created = "";
|
||||||
|
$idrfid = "";
|
||||||
|
$nama = "";
|
||||||
|
$division = "";
|
||||||
|
$mail = "";
|
||||||
|
$alamat = "";
|
||||||
|
$picture = "";
|
||||||
|
|
||||||
|
$created_err = "";
|
||||||
|
$idrfid_err = "";
|
||||||
|
$nama_err = "";
|
||||||
|
$division_err = "";
|
||||||
|
$mail_err = "";
|
||||||
|
$alamat_err = "";
|
||||||
|
$picture_err = "";
|
||||||
|
|
||||||
|
|
||||||
|
// Processing form data when form is submitted
|
||||||
|
if($_SERVER["REQUEST_METHOD"] == "POST"){
|
||||||
|
/*
|
||||||
|
// Validate input
|
||||||
|
$input_address = trim($_POST["address"]);
|
||||||
|
if(empty($input_address)){
|
||||||
|
$address_err = "Please enter an address.";
|
||||||
|
} else{
|
||||||
|
$address = $input_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check input errors before inserting in database
|
||||||
|
if(empty($name_err) && empty($address_err) && empty($salary_err)){
|
||||||
|
// Prepare an insert statement
|
||||||
|
*/
|
||||||
|
$created = date("Y-m-d");
|
||||||
|
$idrfid = trim($_POST["idrfid"]);
|
||||||
|
$nama = trim($_POST["nama"]);
|
||||||
|
$division = trim($_POST["division"]);
|
||||||
|
$mail = trim($_POST["mail"]);
|
||||||
|
$alamat = trim($_POST["alamat"]);
|
||||||
|
$picture = "";
|
||||||
|
|
||||||
|
|
||||||
|
$dsn = "mysql:host=$db_server;dbname=$db_name;charset=utf8mb4";
|
||||||
|
$options = [
|
||||||
|
PDO::ATTR_EMULATE_PREPARES => false, // turn off emulation mode for "real" prepared statements
|
||||||
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, //turn on errors in the form of exceptions
|
||||||
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, //make the default fetch be an associative array
|
||||||
|
];
|
||||||
|
try {
|
||||||
|
$pdo = new PDO($dsn, $db_user, $db_password, $options);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
error_log($e->getMessage());
|
||||||
|
exit('Something weird happened'); //something a user can understand
|
||||||
|
}
|
||||||
|
$stmt = $pdo->prepare("INSERT INTO data_karyawan (created,idrfid,nama,division,mail,alamat,picture) VALUES (?,?,?,?,?,?,?)");
|
||||||
|
|
||||||
|
if($stmt->execute([ $created,$idrfid,$nama,$division,$mail,$alamat,$picture ])) {
|
||||||
|
$stmt = null;
|
||||||
|
|
||||||
|
} else{
|
||||||
|
echo "Gagal mendaftarkan data";
|
||||||
|
}
|
||||||
|
|
||||||
|
//hapus seluruh data invalid
|
||||||
|
// Prepare a delete statement
|
||||||
|
$stmt = $pdo->prepare("DELETE FROM data_invalid WHERE idrfid = :idrfid");
|
||||||
|
$stmt->bindParam(':idrfid', $idrfid);
|
||||||
|
if($stmt->execute()) {
|
||||||
|
$stmt = null;
|
||||||
|
// Records deleted successfully. Redirect to landing page
|
||||||
|
echo '<script language="javascript" type="text/javascript">
|
||||||
|
alert("Data '.$idrfid.' berhasil ditambahkan atas nama '.$nama.'");
|
||||||
|
window.location.replace("data_invalid-index.php");
|
||||||
|
</script>';
|
||||||
|
exit();
|
||||||
|
}else{
|
||||||
|
echo "Gagal menghapus data";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
|
||||||
|
<title>PT. Mantap - Dashboard</title>
|
||||||
|
|
||||||
|
<!-- Custom fonts for this template-->
|
||||||
|
<link href="../src/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this template-->
|
||||||
|
<link href="../src/css/sb-admin-2.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this page -->
|
||||||
|
<link href="../src/vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body id="page-top">
|
||||||
|
|
||||||
|
<!-- Page Wrapper -->
|
||||||
|
<div id="wrapper">
|
||||||
|
|
||||||
|
<!-- Sidebar -->
|
||||||
|
<?php include 'partial_sidebar.php';?>
|
||||||
|
<!-- End of Sidebar -->
|
||||||
|
|
||||||
|
<!-- Content Wrapper -->
|
||||||
|
<div id="content-wrapper" class="d-flex flex-column">
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
|
<div id="content">
|
||||||
|
|
||||||
|
<!-- Topbar -->
|
||||||
|
<?php include 'partial_topbar.php';?>
|
||||||
|
<!-- End of Topbar -->
|
||||||
|
|
||||||
|
<!-- Begin Page Content -->
|
||||||
|
<div class="container-fluid">
|
||||||
|
|
||||||
|
<!-- Page Heading -->
|
||||||
|
<h1 class="h3 mb-2 text-gray-800">Data Kartu Invalid</h1>
|
||||||
|
<div class="card shadow mb-4">
|
||||||
|
<div class="card-header py-3">
|
||||||
|
<h6 class="m-0 font-weight-bold text-primary">Daftarkan Kartu Invalid</h6>
|
||||||
|
</div>
|
||||||
|
<div class="card-body" >
|
||||||
|
<div class="col-md-12">
|
||||||
|
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="nama">Nama</label>
|
||||||
|
<input type="text" name="nama" class="form-control" value="<?php echo $nama; ?>" placeholder="Input nama karyawan" required>
|
||||||
|
<span class="help-block"><?php echo $nama_err; ?></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="idrfid">idrfid</label>
|
||||||
|
<input type="text" name="idrfid" class="form-control" value="<?php echo trim($_GET["idrfid"]) ?>" placeholder="Input idrfid kartu absensi" readonly>
|
||||||
|
<span class="help-block"><?php echo $idrfid_err; ?></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="mail">Email</label>
|
||||||
|
<input type="text" name="mail" class="form-control" value="<?php echo $mail; ?>" placeholder="Input email karyawan" required>
|
||||||
|
<span class="help-block"><?php echo $mail_err; ?></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="division">Divisi</label>
|
||||||
|
<select class="form-control" name="division">
|
||||||
|
<option value="Produksi">Produksi</option>
|
||||||
|
<option value="Keuangan">Keuangan</option>
|
||||||
|
<option value="Perlengkapan">Perlengkapan</option>
|
||||||
|
<option value="Personalia">Personalia</option>
|
||||||
|
<option value="Keteknikan">Keteknikan</option>
|
||||||
|
</select>
|
||||||
|
<!--
|
||||||
|
<input type="text" name="division" class="form-control" value="<?php echo $division; ?>" placeholder="Input divisi/bagian" required>
|
||||||
|
-->
|
||||||
|
<span class="help-block"><?php echo $division_err; ?></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="alamat">Alamat</label>
|
||||||
|
<textarea name="alamat" class="form-control" placeholder="Input alamat rumah karyawan"><?php echo $alamat ; ?></textarea>
|
||||||
|
<span class="help-block"><?php echo $alamat_err; ?></span>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="row justify-content-end">
|
||||||
|
<input type="submit" class="btn btn-success" value="Tambah">  
|
||||||
|
<a href="data_invalid-index.php" class="btn btn-primary">Batal</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- /.container-fluid -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Main Content -->
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<footer class="sticky-footer bg-white">
|
||||||
|
<div class="container my-auto">
|
||||||
|
<div class="copyright text-center my-auto">
|
||||||
|
<span>Copyright © Arief HIdayatullah</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
<!-- End of Footer -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Content Wrapper -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Page Wrapper -->
|
||||||
|
|
||||||
|
<!-- Scroll to Top Button-->
|
||||||
|
<a class="scroll-to-top rounded" href="#page-top">
|
||||||
|
<i class="fas fa-angle-up"></i>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- Logout Modal-->
|
||||||
|
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="exampleModalLabel">Ready to Leave?</h5>
|
||||||
|
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">Select "Logout" below if you are ready to end your current session.</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||||
|
<a class="btn btn-primary" href="login.html">Logout</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Bootstrap core JavaScript-->
|
||||||
|
<script src="../src/vendor/jquery/jquery.min.js"></script>
|
||||||
|
<script src="../src/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Custom scripts for all pages-->
|
||||||
|
<script src="../src/js/sb-admin-2.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,175 @@
|
||||||
|
<?php
|
||||||
|
// Include config file
|
||||||
|
require_once "config.php";
|
||||||
|
|
||||||
|
|
||||||
|
if($_SERVER["REQUEST_METHOD"] == "POST"){
|
||||||
|
// Prepare a delete statement
|
||||||
|
$sql = "TRUNCATE TABLE data_invalid";
|
||||||
|
|
||||||
|
if($stmt = mysqli_prepare($link, $sql)){
|
||||||
|
// Attempt to execute the prepared statement
|
||||||
|
if(mysqli_stmt_execute($stmt)){
|
||||||
|
// Records deleted successfully. Redirect to landing page
|
||||||
|
echo '<script language="javascript" type="text/javascript">
|
||||||
|
alert("Seluruh Data berhasil dihapus");
|
||||||
|
window.location.replace("data_invalid-index.php");
|
||||||
|
</script>';
|
||||||
|
exit();
|
||||||
|
} else{
|
||||||
|
echo "Oops! Something went wrong. Please try again later.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
// Prepare a select statement
|
||||||
|
$sql = "SELECT * FROM data_invalid";
|
||||||
|
|
||||||
|
if($stmt = mysqli_prepare($link, $sql)){
|
||||||
|
// Attempt to execute the prepared statement
|
||||||
|
if(mysqli_stmt_execute($stmt)){
|
||||||
|
$result = mysqli_stmt_get_result($stmt);
|
||||||
|
$rowcount=mysqli_num_rows($result);
|
||||||
|
|
||||||
|
} else{
|
||||||
|
echo "Oops! Something went wrong. Please try again later.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close statement
|
||||||
|
mysqli_stmt_close($stmt);
|
||||||
|
|
||||||
|
// Close connection
|
||||||
|
mysqli_close($link);
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
|
||||||
|
<title>PT. Mantap - Dashboard</title>
|
||||||
|
|
||||||
|
<!-- Custom fonts for this template-->
|
||||||
|
<link href="../src/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this template-->
|
||||||
|
<link href="../src/css/sb-admin-2.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this page -->
|
||||||
|
<link href="../src/vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body id="page-top">
|
||||||
|
|
||||||
|
<!-- Page Wrapper -->
|
||||||
|
<div id="wrapper">
|
||||||
|
|
||||||
|
<!-- Sidebar -->
|
||||||
|
<?php include 'partial_sidebar.php';?>
|
||||||
|
<!-- End of Sidebar -->
|
||||||
|
|
||||||
|
<!-- Content Wrapper -->
|
||||||
|
<div id="content-wrapper" class="d-flex flex-column">
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
|
<div id="content">
|
||||||
|
|
||||||
|
<!-- Topbar -->
|
||||||
|
<?php include 'partial_topbar.php';?>
|
||||||
|
<!-- End of Topbar -->
|
||||||
|
|
||||||
|
<!-- Begin Page Content -->
|
||||||
|
<div class="container-fluid">
|
||||||
|
|
||||||
|
<!-- Page Heading -->
|
||||||
|
<h1 class="h3 mb-2 text-gray-800">Data Karyawan</h1>
|
||||||
|
<div class="card shadow mb-4">
|
||||||
|
<div class="card-header py-3">
|
||||||
|
<h6 class="m-0 font-weight-bold text-primary">Hapus Data</h6>
|
||||||
|
</div>
|
||||||
|
<div class="card-body" >
|
||||||
|
<div class="col-md-12 ">
|
||||||
|
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
<p>Apakah anda ingin menghapus seluruh data kartu invalid?</p>
|
||||||
|
<p>Total Data: <b><?php echo $rowcount; ?></b></p><br>
|
||||||
|
</div>
|
||||||
|
<input type="hidden" name="id" value="<?php echo $row["id"]; ?>"/>
|
||||||
|
<hr>
|
||||||
|
<div class="row justify-content-end">
|
||||||
|
<input type="submit" value="Ya" class="btn btn-danger">  
|
||||||
|
<a href="data_invalid-index.php" class="btn btn-primary">Batal</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- /.container-fluid -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Main Content -->
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<footer class="sticky-footer bg-white">
|
||||||
|
<div class="container my-auto">
|
||||||
|
<div class="copyright text-center my-auto">
|
||||||
|
<span>Copyright © Arief HIdayatullah</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
<!-- End of Footer -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Content Wrapper -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Page Wrapper -->
|
||||||
|
|
||||||
|
<!-- Scroll to Top Button-->
|
||||||
|
<a class="scroll-to-top rounded" href="#page-top">
|
||||||
|
<i class="fas fa-angle-up"></i>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- Logout Modal-->
|
||||||
|
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="exampleModalLabel">Ready to Leave?</h5>
|
||||||
|
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">Select "Logout" below if you are ready to end your current session.</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||||
|
<a class="btn btn-primary" href="login.html">Logout</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Custom scripts for all pages-->
|
||||||
|
<script src="../src/js/sb-admin-2.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Bootstrap core JavaScript-->
|
||||||
|
<script src="../src/vendor/jquery/jquery.min.js"></script>
|
||||||
|
<script src="../src/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
// Process delete operation after confirmation
|
||||||
|
if(isset($_POST["id"]) && !empty($_POST["id"])){
|
||||||
|
// Include config file
|
||||||
|
require_once "config.php";
|
||||||
|
|
||||||
|
// Prepare a delete statement
|
||||||
|
$sql = "DELETE FROM data_invalid WHERE id = ?";
|
||||||
|
|
||||||
|
if($stmt = mysqli_prepare($link, $sql)){
|
||||||
|
// Bind variables to the prepared statement as parameters
|
||||||
|
mysqli_stmt_bind_param($stmt, "i", $param_id);
|
||||||
|
|
||||||
|
// Set parameters
|
||||||
|
$param_id = trim($_POST["id"]);
|
||||||
|
|
||||||
|
// Attempt to execute the prepared statement
|
||||||
|
if(mysqli_stmt_execute($stmt)){
|
||||||
|
// Records deleted successfully. Redirect to landing page
|
||||||
|
echo '<script language="javascript" type="text/javascript">
|
||||||
|
alert("Data berhasil dihapus");
|
||||||
|
window.location.replace("data_invalid-index.php");
|
||||||
|
</script>';
|
||||||
|
exit();
|
||||||
|
} else{
|
||||||
|
echo "Oops! Something went wrong. Please try again later.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close statement
|
||||||
|
mysqli_stmt_close($stmt);
|
||||||
|
|
||||||
|
// Close connection
|
||||||
|
mysqli_close($link);
|
||||||
|
} else{
|
||||||
|
// Check existence of id parameter
|
||||||
|
if(empty(trim($_GET["id"]))){
|
||||||
|
// URL doesn't contain id parameter. Redirect to error page
|
||||||
|
header("location: error.php");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
@ -0,0 +1,186 @@
|
||||||
|
<?php
|
||||||
|
// Check existence of id parameter before processing further
|
||||||
|
if(isset($_GET["id"]) && !empty(trim($_GET["id"]))){
|
||||||
|
// Include config file
|
||||||
|
require_once "config.php";
|
||||||
|
|
||||||
|
// Prepare a select statement
|
||||||
|
$sql = "SELECT * FROM data_invalid WHERE id = ?";
|
||||||
|
|
||||||
|
if($stmt = mysqli_prepare($link, $sql)){
|
||||||
|
// Bind variables to the prepared statement as parameters
|
||||||
|
mysqli_stmt_bind_param($stmt, "i", $param_id);
|
||||||
|
|
||||||
|
// Set parameters
|
||||||
|
$param_id = trim($_GET["id"]);
|
||||||
|
|
||||||
|
// Attempt to execute the prepared statement
|
||||||
|
if(mysqli_stmt_execute($stmt)){
|
||||||
|
$result = mysqli_stmt_get_result($stmt);
|
||||||
|
|
||||||
|
if(mysqli_num_rows($result) == 1){
|
||||||
|
/* Fetch result row as an associative array. Since the result set
|
||||||
|
contains only one row, we don't need to use while loop */
|
||||||
|
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
|
||||||
|
|
||||||
|
/* Retrieve individual field value
|
||||||
|
{INDIVIDUAL_FIELDS}
|
||||||
|
$name = $row["name"];
|
||||||
|
$address = $row["address"];
|
||||||
|
$salary = $row["salary"];
|
||||||
|
*/
|
||||||
|
} else{
|
||||||
|
// URL doesn't contain valid id parameter. Redirect to error page
|
||||||
|
header("location: error.php");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else{
|
||||||
|
echo "Oops! Something went wrong. Please try again later.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close statement
|
||||||
|
mysqli_stmt_close($stmt);
|
||||||
|
|
||||||
|
// Close connection
|
||||||
|
mysqli_close($link);
|
||||||
|
} else{
|
||||||
|
// URL doesn't contain id parameter. Redirect to error page
|
||||||
|
header("location: error.php");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
|
||||||
|
<title>PT. Mantap - Dashboard</title>
|
||||||
|
|
||||||
|
<!-- Custom fonts for this template-->
|
||||||
|
<link href="../src/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this template-->
|
||||||
|
<link href="../src/css/sb-admin-2.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this page -->
|
||||||
|
<link href="../src/vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body id="page-top">
|
||||||
|
|
||||||
|
<!-- Page Wrapper -->
|
||||||
|
<div id="wrapper">
|
||||||
|
|
||||||
|
<!-- Sidebar -->
|
||||||
|
<?php include 'partial_sidebar.php';?>
|
||||||
|
<!-- End of Sidebar -->
|
||||||
|
|
||||||
|
<!-- Content Wrapper -->
|
||||||
|
<div id="content-wrapper" class="d-flex flex-column">
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
|
<div id="content">
|
||||||
|
|
||||||
|
<!-- Topbar -->
|
||||||
|
<?php include 'partial_topbar.php';?>
|
||||||
|
<!-- End of Topbar -->
|
||||||
|
|
||||||
|
<!-- Begin Page Content -->
|
||||||
|
<div class="container-fluid">
|
||||||
|
|
||||||
|
<!-- Page Heading -->
|
||||||
|
<h1 class="h3 mb-2 text-gray-800">Data Karyawan</h1>
|
||||||
|
<div class="card shadow mb-4">
|
||||||
|
<div class="card-header py-3">
|
||||||
|
<h6 class="m-0 font-weight-bold text-primary">Hapus Data</h6>
|
||||||
|
</div>
|
||||||
|
<div class="card-body" >
|
||||||
|
<div class="col-md-12 ">
|
||||||
|
<form action="data_invalid-delete-ok.php" method="post">
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
<p>Apakah anda ingin menghapus data ini?</p>
|
||||||
|
<p>idrfid : <b><?php echo $row["idrfid"]; ?></b> <br>
|
||||||
|
Tanggal : <?php echo $row["tgl"]; ?><br>
|
||||||
|
Jam Tap : <?php echo $row["rekap_masuk"]; ?><br>
|
||||||
|
Status : <?php echo $row["status1"]; ?></p><br>
|
||||||
|
</div>
|
||||||
|
<input type="hidden" name="id" value="<?php echo $row["id"]; ?>"/>
|
||||||
|
<hr>
|
||||||
|
<div class="row justify-content-end">
|
||||||
|
<input type="submit" value="Ya" class="btn btn-danger">  
|
||||||
|
<a href="data_invalid-index.php" class="btn btn-primary">Batal</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- /.container-fluid -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Main Content -->
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<footer class="sticky-footer bg-white">
|
||||||
|
<div class="container my-auto">
|
||||||
|
<div class="copyright text-center my-auto">
|
||||||
|
<span>Copyright © Arief HIdayatullah</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
<!-- End of Footer -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Content Wrapper -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Page Wrapper -->
|
||||||
|
|
||||||
|
<!-- Scroll to Top Button-->
|
||||||
|
<a class="scroll-to-top rounded" href="#page-top">
|
||||||
|
<i class="fas fa-angle-up"></i>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- Logout Modal-->
|
||||||
|
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="exampleModalLabel">Ready to Leave?</h5>
|
||||||
|
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">Select "Logout" below if you are ready to end your current session.</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||||
|
<a class="btn btn-primary" href="login.html">Logout</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Custom scripts for all pages-->
|
||||||
|
<script src="../src/js/sb-admin-2.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Bootstrap core JavaScript-->
|
||||||
|
<script src="../src/vendor/jquery/jquery.min.js"></script>
|
||||||
|
<script src="../src/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,248 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
|
||||||
|
<title>R-collection - Dashboard</title>
|
||||||
|
|
||||||
|
<!-- Custom fonts for this template-->
|
||||||
|
<link href="../src/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this template-->
|
||||||
|
<link href="../src/css/sb-admin-2.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this page -->
|
||||||
|
<link href="../src/vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Bootstrap core JavaScript-->
|
||||||
|
<script src="../src/vendor/jquery/jquery.min.js"></script>
|
||||||
|
<script src="../src/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(document).ready(function(){
|
||||||
|
$('[data-toggle="tooltip"]').tooltip();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body id="page-top">
|
||||||
|
|
||||||
|
<!-- Page Wrapper -->
|
||||||
|
<div id="wrapper">
|
||||||
|
|
||||||
|
<!-- Sidebar -->
|
||||||
|
<?php include 'partial_sidebar.php';?>
|
||||||
|
<!-- End of Sidebar -->
|
||||||
|
|
||||||
|
<!-- Content Wrapper -->
|
||||||
|
<div id="content-wrapper" class="d-flex flex-column">
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
|
<div id="content">
|
||||||
|
|
||||||
|
<!-- Topbar -->
|
||||||
|
<?php include 'partial_topbar.php';?>
|
||||||
|
<!-- End of Topbar -->
|
||||||
|
|
||||||
|
<!-- Begin Page Content -->
|
||||||
|
<div class="container-fluid">
|
||||||
|
|
||||||
|
<!-- Page Heading -->
|
||||||
|
<h1 class="h3 mb-2 text-gray-800">Data Kartu Invalid</h1>
|
||||||
|
|
||||||
|
<!-- DataTales Example -->
|
||||||
|
<div class="card shadow mb-4">
|
||||||
|
<div class="card-header py-3">
|
||||||
|
<h6 class="m-0 font-weight-bold text-primary">Kartu tidak terdaftar</h6>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<a href="data_invalid-delete-all.php" class="btn btn-danger pull-right" id="DelAllBtn">Hapus Semua Data</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<form action="data_karyawan-index.php" method="get">
|
||||||
|
<div class="col">
|
||||||
|
<input type="text" class="form-control" placeholder="Pencarian data kartu invalid" name="search">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// Include config file
|
||||||
|
require_once "config.php";
|
||||||
|
|
||||||
|
//Pagination
|
||||||
|
if (isset($_GET['pageno'])) {
|
||||||
|
$pageno = $_GET['pageno'];
|
||||||
|
} else {
|
||||||
|
$pageno = 1;
|
||||||
|
}
|
||||||
|
$no_of_records_per_page = 25;
|
||||||
|
$offset = ($pageno-1) * $no_of_records_per_page;
|
||||||
|
|
||||||
|
$total_pages_sql = "SELECT COUNT(*) FROM data_invalid";
|
||||||
|
$result = mysqli_query($link,$total_pages_sql);
|
||||||
|
$total_rows = mysqli_fetch_array($result)[0];
|
||||||
|
$total_pages = ceil($total_rows / $no_of_records_per_page);
|
||||||
|
|
||||||
|
//Column sorting on column name
|
||||||
|
$orderBy = array('tgl', 'rekap_masuk', 'idrfid', 'id');
|
||||||
|
$order = 'id';
|
||||||
|
if (isset($_GET['order']) && in_array($_GET['order'], $orderBy)) {
|
||||||
|
$order = $_GET['order'];
|
||||||
|
}
|
||||||
|
|
||||||
|
//Column sort order
|
||||||
|
$sortBy = array('asc', 'desc'); $sort = 'desc';
|
||||||
|
if (isset($_GET['sort']) && in_array($_GET['sort'], $sortBy)) {
|
||||||
|
if($_GET['sort']=='asc') {
|
||||||
|
$sort='desc';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$sort='asc';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Attempt select query execution
|
||||||
|
$sql = "SELECT * FROM data_invalid ORDER BY $order $sort LIMIT $offset, $no_of_records_per_page";
|
||||||
|
|
||||||
|
if(!empty($_GET['search'])) {
|
||||||
|
$search = ($_GET['search']);
|
||||||
|
$sql = "SELECT * FROM data_invalid
|
||||||
|
WHERE CONCAT (tgl,rekap_masuk,idrfid,id)
|
||||||
|
LIKE '%$search%' COLLATE utf8mb4_general_ci
|
||||||
|
ORDER BY $order $sort
|
||||||
|
LIMIT $offset, $no_of_records_per_page";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$search = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if($result = mysqli_query($link, $sql)){
|
||||||
|
if(mysqli_num_rows($result) > 0){
|
||||||
|
echo "<table class='table table-bordered table-striped'>";
|
||||||
|
echo "<thead>";
|
||||||
|
echo "<tr>";
|
||||||
|
echo "<th><a href=?search=$search&sort=&order=tgl&sort=$sort>tgl</th>";
|
||||||
|
echo "<th><a href=?search=$search&sort=&order=rekap_masuk&sort=$sort>rekap_masuk</th>";
|
||||||
|
echo "<th><a href=?search=$search&sort=&order=idrfid&sort=$sort>idrfid</th>";
|
||||||
|
echo "<th><a href=?search=$search&sort=&order=id&sort=$sort>id</th>";
|
||||||
|
|
||||||
|
echo "<th>Action</th>";
|
||||||
|
echo "</tr>";
|
||||||
|
echo "</thead>";
|
||||||
|
echo "<tbody>";
|
||||||
|
while($row = mysqli_fetch_array($result)){
|
||||||
|
echo "<tr>";
|
||||||
|
echo "<td>" . $row['tgl'] . "</td>";echo "<td>" . $row['rekap_masuk'] . "</td>";echo "<td>" . $row['idrfid'] . "</td>";echo "<td>" . $row['id'] . "</td>";
|
||||||
|
echo "<td>";
|
||||||
|
echo "<a href='data_invalid-add.php?idrfid=". $row['idrfid'] ."' title='Daftarkan' data-toggle='tooltip'><span class='fa fa-plus'></span></a>  ";
|
||||||
|
echo "<a href='data_invalid-delete.php?id=". $row['id'] ."' title='Hapus' data-toggle='tooltip'><span class='fa fa-trash'></span></a>  ";
|
||||||
|
echo "<a href='data_registrasi-create.php?id=". $row['id'] ."' title='Tambahkan Akun' data-toggle='tooltip'><span class='fas fa-fw a-solid fa-user-plus'></span></a>";
|
||||||
|
echo "</td>";
|
||||||
|
echo "</tr>";
|
||||||
|
}
|
||||||
|
echo "</tbody>";
|
||||||
|
echo "</table>";
|
||||||
|
?>
|
||||||
|
<!-- <nav aria-label="Page navigation example">
|
||||||
|
<ul class="pagination">
|
||||||
|
<li class="page-item"><a class="page-link" href="?pageno=1">First</a></li>
|
||||||
|
<li class="page-item <?php if($pageno <= 1){ echo 'disabled'; } ?>">
|
||||||
|
<a class="page-link" href="<?php if($pageno <= 1){ echo '#'; } else { echo "?pageno=".($pageno - 1); } ?>">Prev</a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item <?php if($pageno >= $total_pages){ echo 'disabled'; } ?>">
|
||||||
|
<a class="page-link" href="<?php if($pageno >= $total_pages){ echo '#'; } else { echo "?pageno=".($pageno + 1); } ?>">Next</a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item"><a class="page-link" href="?pageno=<?php echo $total_pages; ?>">Last</a></li>
|
||||||
|
</ul>
|
||||||
|
</nav> -->
|
||||||
|
<?php
|
||||||
|
// Free result set
|
||||||
|
mysqli_free_result($result);
|
||||||
|
} else{
|
||||||
|
echo "<p class='lead'><em>No records were found.</em></p>";
|
||||||
|
echo '<script language="javascript" type="text/javascript">
|
||||||
|
document.getElementById("DelAllBtn").className = "btn btn-danger pull-right disabled";
|
||||||
|
</script>';
|
||||||
|
}
|
||||||
|
} else{
|
||||||
|
echo "ERROR: Could not able to execute $sql. " . mysqli_error($link);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close connection
|
||||||
|
mysqli_close($link);
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- /.container-fluid -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Main Content -->
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<footer class="sticky-footer bg-white">
|
||||||
|
<div class="container my-auto">
|
||||||
|
<div class="copyright text-center my-auto">
|
||||||
|
<span>Copyright © Arief HIdayatullah</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
<!-- End of Footer -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Content Wrapper -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Page Wrapper -->
|
||||||
|
|
||||||
|
<!-- Scroll to Top Button-->
|
||||||
|
<a class="scroll-to-top rounded" href="#page-top">
|
||||||
|
<i class="fas fa-angle-up"></i>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- Logout Modal-->
|
||||||
|
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="exampleModalLabel">Ready to Leave?</h5>
|
||||||
|
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">Select "Logout" below if you are ready to end your current session.</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||||
|
<a class="btn btn-primary" href="http://localhost/rfidcam/">Logout</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Page level plugins -->
|
||||||
|
<script src="../src/vendor/datatables/jquery.dataTables.min.js"></script>
|
||||||
|
<script src="../src/vendor/datatables/dataTables.bootstrap4.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Custom scripts for all pages-->
|
||||||
|
<script src="../src/js/sb-admin-2.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,180 @@
|
||||||
|
<?php
|
||||||
|
date_default_timezone_set('Asia/Jakarta');
|
||||||
|
// Sertakan file konfigurasi
|
||||||
|
require_once "config.php";
|
||||||
|
|
||||||
|
// Definisikan variabel dan inisialisasi dengan nilai kosong
|
||||||
|
$created = "";
|
||||||
|
$idrfid = "";
|
||||||
|
$nama = "";
|
||||||
|
$division = "";
|
||||||
|
$mail = "";
|
||||||
|
$alamat = "";
|
||||||
|
$picture = "";
|
||||||
|
|
||||||
|
$created_err = "";
|
||||||
|
$idrfid_err = "";
|
||||||
|
$nama_err = "";
|
||||||
|
$division_err = "";
|
||||||
|
$mail_err = "";
|
||||||
|
$alamat_err = "";
|
||||||
|
$picture_err = "";
|
||||||
|
|
||||||
|
// Memproses data formulir saat formulir dikirimkan
|
||||||
|
if($_SERVER["REQUEST_METHOD"] == "POST"){
|
||||||
|
$created = date("Y-m-d");
|
||||||
|
$idrfid = trim($_POST["idrfid"]);
|
||||||
|
$nama = trim($_POST["nama"]);
|
||||||
|
$division = trim($_POST["division"]);
|
||||||
|
$mail = trim($_POST["mail"]);
|
||||||
|
$alamat = trim($_POST["alamat"]);
|
||||||
|
$picture = "";
|
||||||
|
|
||||||
|
// Konfigurasi koneksi database
|
||||||
|
$dsn = "mysql:host=$db_server;dbname=$db_name;charset=utf8mb4";
|
||||||
|
$options = [
|
||||||
|
PDO::ATTR_EMULATE_PREPARES => false,
|
||||||
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$pdo = new PDO($dsn, $db_user, $db_password, $options);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
error_log($e->getMessage());
|
||||||
|
exit('Terjadi kesalahan');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Periksa apakah idrfid sudah ada di database
|
||||||
|
$stmt = $pdo->prepare("SELECT id FROM data_karyawan WHERE idrfid = ?");
|
||||||
|
$stmt->execute([$idrfid]);
|
||||||
|
if($stmt->rowCount() > 0){
|
||||||
|
$idrfid_err = "ID RFID ini sudah terdaftar.";
|
||||||
|
} else {
|
||||||
|
$stmt = $pdo->prepare("INSERT INTO data_karyawan (created,idrfid,nama,division,mail,alamat,picture) VALUES (?,?,?,?,?,?,?)");
|
||||||
|
|
||||||
|
if($stmt->execute([$created, $idrfid, $nama, $division, $mail, $alamat, $picture])) {
|
||||||
|
$stmt = null;
|
||||||
|
echo '<script language="javascript" type="text/javascript">
|
||||||
|
alert("Data berhasil ditambahkan");
|
||||||
|
window.location.replace("data_karyawan-index.php");
|
||||||
|
</script>';
|
||||||
|
} else {
|
||||||
|
echo "Terjadi kesalahan. Silakan coba lagi nanti.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
<title>PT. Mantap - Dashboard</title>
|
||||||
|
<link href="../src/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">
|
||||||
|
<link href="../src/css/sb-admin-2.min.css" rel="stylesheet">
|
||||||
|
<link href="../src/vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
.error-message {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body id="page-top">
|
||||||
|
<div id="wrapper">
|
||||||
|
<?php include 'partial_sidebar.php';?>
|
||||||
|
<div id="content-wrapper" class="d-flex flex-column">
|
||||||
|
<div id="content">
|
||||||
|
<?php include 'partial_topbar.php';?>
|
||||||
|
<div class="container-fluid">
|
||||||
|
<h1 class="h3 mb-2 text-gray-800">Data Karyawan</h1>
|
||||||
|
<div class="card shadow mb-4">
|
||||||
|
<div class="card-header py-3">
|
||||||
|
<h6 class="m-0 font-weight-bold text-primary">Tambah Data</h6>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="nama">Nama</label>
|
||||||
|
<input type="text" name="nama" class="form-control" value="<?php echo $nama; ?>" placeholder="Input nama karyawan" required>
|
||||||
|
<span class="help-block"><?php echo $nama_err; ?></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="idrfid">ID RFID</label>
|
||||||
|
<input type="text" name="idrfid" class="form-control" value="<?php echo $idrfid; ?>" placeholder="Input ID RFID kartu absensi" required>
|
||||||
|
<span class="error-message"><?php echo $idrfid_err; ?></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="mail">Email</label>
|
||||||
|
<input type="text" name="mail" class="form-control" value="<?php echo $mail; ?>" placeholder="Input email karyawan" required>
|
||||||
|
<span class="help-block"><?php echo $mail_err; ?></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="division">Divisi</label>
|
||||||
|
<select class="form-control" name="division">
|
||||||
|
<option value="Produksi">Produksi</option>
|
||||||
|
<option value="Keuangan">Keuangan</option>
|
||||||
|
<option value="Perlengkapan">Perlengkapan</option>
|
||||||
|
<option value="Personalia">Personalia</option>
|
||||||
|
<option value="Keteknikan">Keteknikan</option>
|
||||||
|
</select>
|
||||||
|
<span class="help-block"><?php echo $division_err; ?></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="alamat">Alamat</label>
|
||||||
|
<textarea name="alamat" class="form-control" placeholder="Input alamat rumah karyawan"><?php echo $alamat; ?></textarea>
|
||||||
|
<span class="help-block"><?php echo $alamat_err; ?></span>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="row justify-content-end">
|
||||||
|
<input type="submit" class="btn btn-success" value="Tambah">  
|
||||||
|
<a href="data_karyawan-index.php" class="btn btn-primary">Batal</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer class="sticky-footer bg-white">
|
||||||
|
<div class="container my-auto">
|
||||||
|
<div class="copyright text-center my-auto">
|
||||||
|
<span>Copyright © Arief Hidayatullah</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a class="scroll-to-top rounded" href="#page-top">
|
||||||
|
<i class="fas fa-angle-up"></i>
|
||||||
|
</a>
|
||||||
|
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="exampleModalLabel">Siap untuk keluar?</h5>
|
||||||
|
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">Pilih "Logout" di bawah jika Anda siap mengakhiri sesi Anda saat ini.</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-secondary" type="button" data-dismiss="modal">Batal</button>
|
||||||
|
<a class="btn btn-primary" href="login.html">Logout</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="../src/vendor/jquery-easing/jquery.easing.min.js"></script>
|
||||||
|
<script src="../src/js/sb-admin-2.min.js"></script>
|
||||||
|
<script src="../src/vendor/jquery/jquery.min.js"></script>
|
||||||
|
<script src="../src/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
// Process delete operation after confirmation
|
||||||
|
if(isset($_POST["id"]) && !empty($_POST["id"])){
|
||||||
|
// Include config file
|
||||||
|
require_once "config.php";
|
||||||
|
|
||||||
|
// Prepare a delete statement
|
||||||
|
$sql = "DELETE FROM data_karyawan WHERE id = ?";
|
||||||
|
|
||||||
|
if($stmt = mysqli_prepare($link, $sql)){
|
||||||
|
// Bind variables to the prepared statement as parameters
|
||||||
|
mysqli_stmt_bind_param($stmt, "i", $param_id);
|
||||||
|
|
||||||
|
// Set parameters
|
||||||
|
$param_id = trim($_POST["id"]);
|
||||||
|
|
||||||
|
// Attempt to execute the prepared statement
|
||||||
|
if(mysqli_stmt_execute($stmt)){
|
||||||
|
// Records deleted successfully. Redirect to landing page
|
||||||
|
echo '<script language="javascript" type="text/javascript">
|
||||||
|
alert("Data berhasil dihapus");
|
||||||
|
window.location.replace("data_karyawan-index.php");
|
||||||
|
</script>';
|
||||||
|
exit();
|
||||||
|
} else{
|
||||||
|
echo "Oops! Something went wrong. Please try again later.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close statement
|
||||||
|
mysqli_stmt_close($stmt);
|
||||||
|
|
||||||
|
// Close connection
|
||||||
|
mysqli_close($link);
|
||||||
|
} else{
|
||||||
|
// Check existence of id parameter
|
||||||
|
if(empty(trim($_GET["id"]))){
|
||||||
|
// URL doesn't contain id parameter. Redirect to error page
|
||||||
|
header("location: error.php");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
@ -0,0 +1,184 @@
|
||||||
|
<?php
|
||||||
|
// Check existence of id parameter before processing further
|
||||||
|
if(isset($_GET["id"]) && !empty(trim($_GET["id"]))){
|
||||||
|
// Include config file
|
||||||
|
require_once "config.php";
|
||||||
|
|
||||||
|
// Prepare a select statement
|
||||||
|
$sql = "SELECT * FROM data_karyawan WHERE id = ?";
|
||||||
|
|
||||||
|
if($stmt = mysqli_prepare($link, $sql)){
|
||||||
|
// Bind variables to the prepared statement as parameters
|
||||||
|
mysqli_stmt_bind_param($stmt, "i", $param_id);
|
||||||
|
|
||||||
|
// Set parameters
|
||||||
|
$param_id = trim($_GET["id"]);
|
||||||
|
|
||||||
|
// Attempt to execute the prepared statement
|
||||||
|
if(mysqli_stmt_execute($stmt)){
|
||||||
|
$result = mysqli_stmt_get_result($stmt);
|
||||||
|
|
||||||
|
if(mysqli_num_rows($result) == 1){
|
||||||
|
/* Fetch result row as an associative array. Since the result set
|
||||||
|
contains only one row, we don't need to use while loop */
|
||||||
|
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
|
||||||
|
|
||||||
|
/* Retrieve individual field value
|
||||||
|
{INDIVIDUAL_FIELDS}
|
||||||
|
$name = $row["name"];
|
||||||
|
$address = $row["address"];
|
||||||
|
$salary = $row["salary"];
|
||||||
|
*/
|
||||||
|
} else{
|
||||||
|
// URL doesn't contain valid id parameter. Redirect to error page
|
||||||
|
header("location: error.php");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else{
|
||||||
|
echo "Oops! Something went wrong. Please try again later.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close statement
|
||||||
|
mysqli_stmt_close($stmt);
|
||||||
|
|
||||||
|
// Close connection
|
||||||
|
mysqli_close($link);
|
||||||
|
} else{
|
||||||
|
// URL doesn't contain id parameter. Redirect to error page
|
||||||
|
header("location: error.php");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
|
||||||
|
<title>PT. Mantap - Dashboard</title>
|
||||||
|
|
||||||
|
<!-- Custom fonts for this template-->
|
||||||
|
<link href="../src/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this template-->
|
||||||
|
<link href="../src/css/sb-admin-2.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this page -->
|
||||||
|
<link href="../src/vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body id="page-top">
|
||||||
|
|
||||||
|
<!-- Page Wrapper -->
|
||||||
|
<div id="wrapper">
|
||||||
|
|
||||||
|
<!-- Sidebar -->
|
||||||
|
<?php include 'partial_sidebar.php';?>
|
||||||
|
<!-- End of Sidebar -->
|
||||||
|
|
||||||
|
<!-- Content Wrapper -->
|
||||||
|
<div id="content-wrapper" class="d-flex flex-column">
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
|
<div id="content">
|
||||||
|
|
||||||
|
<!-- Topbar -->
|
||||||
|
<?php include 'partial_topbar.php';?>
|
||||||
|
<!-- End of Topbar -->
|
||||||
|
|
||||||
|
<!-- Begin Page Content -->
|
||||||
|
<div class="container-fluid">
|
||||||
|
|
||||||
|
<!-- Page Heading -->
|
||||||
|
<h1 class="h3 mb-2 text-gray-800">Data Karyawan</h1>
|
||||||
|
<div class="card shadow mb-4">
|
||||||
|
<div class="card-header py-3">
|
||||||
|
<h6 class="m-0 font-weight-bold text-primary">Hapus Data</h6>
|
||||||
|
</div>
|
||||||
|
<div class="card-body" >
|
||||||
|
<div class="col-md-12 ">
|
||||||
|
<form action="data_karyawan-delete-ok.php" method="post">
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
<p>Apakah anda ingin menghapus data <b><?php echo $row["nama"]; ?></b> ?</p><br>
|
||||||
|
</div>
|
||||||
|
<input type="hidden" name="id" value="<?php echo $row["id"]; ?>"/>
|
||||||
|
<hr>
|
||||||
|
<div class="row justify-content-end">
|
||||||
|
<input type="submit" value="Ya" class="btn btn-danger">  
|
||||||
|
<a href="data_karyawan-index.php" class="btn btn-primary">Batal</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- /.container-fluid -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Main Content -->
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<footer class="sticky-footer bg-white">
|
||||||
|
<div class="container my-auto">
|
||||||
|
<div class="copyright text-center my-auto">
|
||||||
|
<span>Copyright © Arief HIdayatullah</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
<!-- End of Footer -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Content Wrapper -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Page Wrapper -->
|
||||||
|
|
||||||
|
<!-- Scroll to Top Button-->
|
||||||
|
<a class="scroll-to-top rounded" href="#page-top">
|
||||||
|
<i class="fas fa-angle-up"></i>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- Logout Modal-->
|
||||||
|
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="exampleModalLabel">Ready to Leave?</h5>
|
||||||
|
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">Select "Logout" below if you are ready to end your current session.</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||||
|
<a class="btn btn-primary" href="login.html">Logout</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Bootstrap core JavaScript-->
|
||||||
|
<script src="../src/vendor/jquery/jquery.min.js"></script>
|
||||||
|
<script src="../src/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Custom scripts for all pages-->
|
||||||
|
<script src="../src/js/sb-admin-2.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,249 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
|
||||||
|
<title>R-collection Dashboard</title>
|
||||||
|
|
||||||
|
<!-- Custom fonts for this template-->
|
||||||
|
<link href="../src/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this template-->
|
||||||
|
<link href="../src/css/sb-admin-2.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this page -->
|
||||||
|
<link href="../src/vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Bootstrap core JavaScript-->
|
||||||
|
<script src="../src/vendor/jquery/jquery.min.js"></script>
|
||||||
|
<script src="../src/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(document).ready(function(){
|
||||||
|
$('[data-toggle="tooltip"]').tooltip();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body id="page-top">
|
||||||
|
|
||||||
|
<!-- Page Wrapper -->
|
||||||
|
<div id="wrapper">
|
||||||
|
|
||||||
|
<!-- Sidebar -->
|
||||||
|
<?php include 'partial_sidebar.php';?>
|
||||||
|
<!-- End of Sidebar -->
|
||||||
|
|
||||||
|
<!-- Content Wrapper -->
|
||||||
|
<div id="content-wrapper" class="d-flex flex-column">
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
|
<div id="content">
|
||||||
|
|
||||||
|
<!-- Topbar -->
|
||||||
|
<?php include 'partial_topbar.php';?>
|
||||||
|
<!-- End of Topbar -->
|
||||||
|
|
||||||
|
<!-- Begin Page Content -->
|
||||||
|
<div class="container-fluid">
|
||||||
|
|
||||||
|
<!-- Page Heading -->
|
||||||
|
<h1 class="h3 mb-2 text-gray-800">Data Karyawan</h1>
|
||||||
|
|
||||||
|
<!-- DataTales Example -->
|
||||||
|
<div class="card shadow mb-4">
|
||||||
|
<div class="card-header py-3">
|
||||||
|
<h6 class="m-0 font-weight-bold text-primary">Karyawan Aktif</h6>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<a href="data_karyawan-create.php" class="btn btn-success pull-right">Tambah Data Baru</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<form action="data_karyawan-index.php" method="get">
|
||||||
|
<div class="col">
|
||||||
|
<input type="text" class="form-control" placeholder="Pencarian data karyawan" name="search">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// Include config file
|
||||||
|
require_once "config.php";
|
||||||
|
|
||||||
|
//Pagination
|
||||||
|
if (isset($_GET['pageno'])) {
|
||||||
|
$pageno = $_GET['pageno'];
|
||||||
|
} else {
|
||||||
|
$pageno = 1;
|
||||||
|
}
|
||||||
|
$no_of_records_per_page = 10;
|
||||||
|
$offset = ($pageno-1) * $no_of_records_per_page;
|
||||||
|
|
||||||
|
$total_pages_sql = "SELECT COUNT(*) FROM data_karyawan";
|
||||||
|
$result = mysqli_query($link,$total_pages_sql);
|
||||||
|
$total_rows = mysqli_fetch_array($result)[0];
|
||||||
|
$total_pages = ceil($total_rows / $no_of_records_per_page);
|
||||||
|
|
||||||
|
//Column sorting on column name
|
||||||
|
$orderBy = array('idrfid', 'nama', 'division', 'mail', 'alamat');
|
||||||
|
$order = 'id';
|
||||||
|
if (isset($_GET['order']) && in_array($_GET['order'], $orderBy)) {
|
||||||
|
$order = $_GET['order'];
|
||||||
|
}
|
||||||
|
|
||||||
|
//Column sort order
|
||||||
|
$sortBy = array('asc', 'desc'); $sort = 'desc';
|
||||||
|
if (isset($_GET['sort']) && in_array($_GET['sort'], $sortBy)) {
|
||||||
|
if($_GET['sort']=='asc') {
|
||||||
|
$sort='desc';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$sort='asc';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Attempt select query execution
|
||||||
|
$sql = "SELECT data_karyawan.*, division FROM data_karyawan ORDER BY $order $sort LIMIT $offset, $no_of_records_per_page";
|
||||||
|
|
||||||
|
if(!empty($_GET['search'])) {
|
||||||
|
$search = ($_GET['search']);
|
||||||
|
$sql = "SELECT * FROM data_karyawan
|
||||||
|
WHERE CONCAT (idrfid,nama,division,mail,alamat)
|
||||||
|
LIKE '%$search%' COLLATE utf8mb4_general_ci
|
||||||
|
ORDER BY $order $sort
|
||||||
|
LIMIT $offset, $no_of_records_per_page";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$search = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if($result = mysqli_query($link, $sql)){
|
||||||
|
if(mysqli_num_rows($result) > 0){
|
||||||
|
echo "<table class='table table-bordered table-striped'>";
|
||||||
|
echo "<thead>";
|
||||||
|
echo "<tr>";
|
||||||
|
echo "<th><a href=?search=$search&sort=&order=idrfid&sort=$sort>idrfid</th>";
|
||||||
|
echo "<th><a href=?search=$search&sort=&order=nama&sort=$sort>Nama</th>";
|
||||||
|
echo "<th><a href=?search=$search&sort=&order=division&sort=$sort>Divisi</th>";
|
||||||
|
echo "<th><a href=?search=$search&sort=&order=mail&sort=$sort>Email</th>";
|
||||||
|
echo "<th><a href=?search=$search&sort=&order=alamat&sort=$sort>Alamat</th>";
|
||||||
|
|
||||||
|
|
||||||
|
echo "<th>Action</th>";
|
||||||
|
echo "</tr>";
|
||||||
|
echo "</thead>";
|
||||||
|
echo "<tbody>";
|
||||||
|
while($row = mysqli_fetch_array($result)){
|
||||||
|
echo "<tr>";
|
||||||
|
echo "<td>" . $row['idrfid'] . "</td>";echo "<td>" . $row['nama'] . "</td>";echo "<td>" . $row['division'] . "</td>";echo "<td>" . $row['mail'] . "</td>";echo "<td>" . $row['alamat'] . "</td>";
|
||||||
|
echo "<td>";
|
||||||
|
echo "<a href='data_karyawan-read.php?id=". $row['id'] ."' title='Detail' data-toggle='tooltip'><span class='fa fa-eye'></span></a>  ";
|
||||||
|
echo "<a href='data_karyawan-update.php?id=". $row['id'] ."' title='Edit' data-toggle='tooltip'><span class='fa fa-edit'></span></a> ";
|
||||||
|
echo "<a href='data_karyawan-delete.php?id=". $row['id'] ."' title='Hapus' data-toggle='tooltip'><span class='fa fa-trash'></span></a>";
|
||||||
|
echo "</td>";
|
||||||
|
echo "</tr>";
|
||||||
|
}
|
||||||
|
echo "</tbody>";
|
||||||
|
echo "</table>";
|
||||||
|
?>
|
||||||
|
<nav aria-label="Page navigation example">
|
||||||
|
<ul class="pagination">
|
||||||
|
<li class="page-item"><a class="page-link" href="?pageno=1">First</a></li>
|
||||||
|
<li class="page-item <?php if($pageno <= 1){ echo 'disabled'; } ?>">
|
||||||
|
<a class="page-link" href="<?php if($pageno <= 1){ echo '#'; } else { echo "?pageno=".($pageno - 1); } ?>">Prev</a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item <?php if($pageno >= $total_pages){ echo 'disabled'; } ?>">
|
||||||
|
<a class="page-link" href="<?php if($pageno >= $total_pages){ echo '#'; } else { echo "?pageno=".($pageno + 1); } ?>">Next</a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item"><a class="page-link" href="?pageno=<?php echo $total_pages; ?>">Last</a></li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<?php
|
||||||
|
// Free result set
|
||||||
|
mysqli_free_result($result);
|
||||||
|
} else{
|
||||||
|
echo "<p class='lead'><em>No records were found.</em></p>";
|
||||||
|
}
|
||||||
|
} else{
|
||||||
|
echo "ERROR: Could not able to execute $sql. " . mysqli_error($link);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close connection
|
||||||
|
mysqli_close($link);
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- /.container-fluid -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Main Content -->
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<footer class="sticky-footer bg-white">
|
||||||
|
<div class="container my-auto">
|
||||||
|
<div class="copyright text-center my-auto">
|
||||||
|
<span>Copyright © Arief HIdayatullah</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
<!-- End of Footer -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Content Wrapper -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Page Wrapper -->
|
||||||
|
|
||||||
|
<!-- Scroll to Top Button-->
|
||||||
|
<a class="scroll-to-top rounded" href="#page-top">
|
||||||
|
<i class="fas fa-angle-up"></i>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- Logout Modal-->
|
||||||
|
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="exampleModalLabel">Ready to Leave?</h5>
|
||||||
|
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">Select "Logout" below if you are ready to end your current session.</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||||
|
<a class="btn btn-primary" href="http://localhost/rfidcam/">Logout</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Page level plugins -->
|
||||||
|
<script src="../src/vendor/datatables/jquery.dataTables.min.js"></script>
|
||||||
|
<script src="../src/vendor/datatables/dataTables.bootstrap4.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Custom scripts for all pages-->
|
||||||
|
<script src="../src/js/sb-admin-2.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,199 @@
|
||||||
|
<?php
|
||||||
|
// Check existence of id parameter before processing further
|
||||||
|
if(isset($_GET["id"]) && !empty(trim($_GET["id"]))){
|
||||||
|
// Include config file
|
||||||
|
require_once "config.php";
|
||||||
|
|
||||||
|
// Prepare a select statement
|
||||||
|
$sql = "SELECT * FROM data_karyawan WHERE id = ?";
|
||||||
|
|
||||||
|
if($stmt = mysqli_prepare($link, $sql)){
|
||||||
|
// Bind variables to the prepared statement as parameters
|
||||||
|
mysqli_stmt_bind_param($stmt, "i", $param_id);
|
||||||
|
|
||||||
|
// Set parameters
|
||||||
|
$param_id = trim($_GET["id"]);
|
||||||
|
|
||||||
|
// Attempt to execute the prepared statement
|
||||||
|
if(mysqli_stmt_execute($stmt)){
|
||||||
|
$result = mysqli_stmt_get_result($stmt);
|
||||||
|
|
||||||
|
if(mysqli_num_rows($result) == 1){
|
||||||
|
/* Fetch result row as an associative array. Since the result set
|
||||||
|
contains only one row, we don't need to use while loop */
|
||||||
|
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
|
||||||
|
|
||||||
|
/* Retrieve individual field value
|
||||||
|
{INDIVIDUAL_FIELDS}
|
||||||
|
$name = $row["name"];
|
||||||
|
$address = $row["address"];
|
||||||
|
$salary = $row["salary"];
|
||||||
|
*/
|
||||||
|
} else{
|
||||||
|
// URL doesn't contain valid id parameter. Redirect to error page
|
||||||
|
header("location: error.php");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else{
|
||||||
|
echo "Oops! Something went wrong. Please try again later.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close statement
|
||||||
|
mysqli_stmt_close($stmt);
|
||||||
|
|
||||||
|
// Close connection
|
||||||
|
mysqli_close($link);
|
||||||
|
} else{
|
||||||
|
// URL doesn't contain id parameter. Redirect to error page
|
||||||
|
header("location: error.php");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
|
||||||
|
<title>PT. Mantap - Dashboard</title>
|
||||||
|
|
||||||
|
<!-- Custom fonts for this template-->
|
||||||
|
<link href="../src/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this template-->
|
||||||
|
<link href="../src/css/sb-admin-2.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this page -->
|
||||||
|
<link href="../src/vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body id="page-top">
|
||||||
|
|
||||||
|
<!-- Page Wrapper -->
|
||||||
|
<div id="wrapper">
|
||||||
|
|
||||||
|
<!-- Sidebar -->
|
||||||
|
<?php include 'partial_sidebar.php';?>
|
||||||
|
<!-- End of Sidebar -->
|
||||||
|
|
||||||
|
<!-- Content Wrapper -->
|
||||||
|
<div id="content-wrapper" class="d-flex flex-column">
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
|
<div id="content">
|
||||||
|
|
||||||
|
<!-- Topbar -->
|
||||||
|
<?php include 'partial_topbar.php';?>
|
||||||
|
<!-- End of Topbar -->
|
||||||
|
|
||||||
|
<!-- Begin Page Content -->
|
||||||
|
<div class="container-fluid">
|
||||||
|
|
||||||
|
<!-- Page Heading -->
|
||||||
|
<h1 class="h3 mb-2 text-gray-800">Data Karyawan</h1>
|
||||||
|
<div class="card shadow mb-4">
|
||||||
|
<div class="card-header py-3">
|
||||||
|
<h6 class="m-0 font-weight-bold text-primary">Tambah Data</h6>
|
||||||
|
</div>
|
||||||
|
<div class="card-body" >
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="nama">Nama</label>
|
||||||
|
<input type="text" name="nama" class="form-control" value="<?php echo $row["nama"]; ?>" readonly>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="idrfid">UID</label>
|
||||||
|
<input type="text" name="idrfid" class="form-control" value="<?php echo $row["idrfid"]; ?>" readonly>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="mail">Email</label>
|
||||||
|
<input type="text" name="mail" class="form-control" value="<?php echo $row["mail"]; ?>" readonly>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="division">Divisi</label>
|
||||||
|
<input type="text" name="division" class="form-control" value="<?php echo $row["division"]; ?>" readonly>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="alamat">Alamat</label>
|
||||||
|
<textarea name="alamat" class="form-control" readonly><?php echo $row["alamat"]; ?></textarea>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="row justify-content-end">
|
||||||
|
<a href="data_karyawan-index.php" class="btn btn-primary">Kembali</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- /.container-fluid -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Main Content -->
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<footer class="sticky-footer bg-white">
|
||||||
|
<div class="container my-auto">
|
||||||
|
<div class="copyright text-center my-auto">
|
||||||
|
<span>Copyright © Arief HIdayatullah</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
<!-- End of Footer -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Content Wrapper -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Page Wrapper -->
|
||||||
|
|
||||||
|
<!-- Scroll to Top Button-->
|
||||||
|
<a class="scroll-to-top rounded" href="#page-top">
|
||||||
|
<i class="fas fa-angle-up"></i>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- Logout Modal-->
|
||||||
|
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="exampleModalLabel">Ready to Leave?</h5>
|
||||||
|
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">Select "Logout" below if you are ready to end your current session.</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||||
|
<a class="btn btn-primary" href="login.html">Logout</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Bootstrap core JavaScript-->
|
||||||
|
<script src="../src/vendor/jquery/jquery.min.js"></script>
|
||||||
|
<script src="../src/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Custom scripts for all pages-->
|
||||||
|
<script src="../src/js/sb-admin-2.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,292 @@
|
||||||
|
<?php
|
||||||
|
// Include config file
|
||||||
|
require_once "config.php";
|
||||||
|
|
||||||
|
// Define variables and initialize with empty values
|
||||||
|
$created = "";
|
||||||
|
$idrfid = "";
|
||||||
|
$nama = "";
|
||||||
|
$division = "";
|
||||||
|
$mail = "";
|
||||||
|
$alamat = "";
|
||||||
|
$picture = "";
|
||||||
|
|
||||||
|
$created_err = "";
|
||||||
|
$idrfid_err = "";
|
||||||
|
$nama_err = "";
|
||||||
|
$division_err = "";
|
||||||
|
$mail_err = "";
|
||||||
|
$alamat_err = "";
|
||||||
|
$picture_err = "";
|
||||||
|
|
||||||
|
|
||||||
|
// Processing form data when form is submitted
|
||||||
|
if(isset($_POST["id"]) && !empty($_POST["id"])){
|
||||||
|
// Get hidden input value
|
||||||
|
$id = $_POST["id"];
|
||||||
|
|
||||||
|
// Field validation
|
||||||
|
|
||||||
|
// Check input errors before inserting in database
|
||||||
|
// if(empty($name_err) && empty($address_err) && empty($salary_err)){
|
||||||
|
// Prepare an update statement
|
||||||
|
|
||||||
|
$created = trim($_POST["created"]);
|
||||||
|
$idrfid = trim($_POST["idrfid"]);
|
||||||
|
$nama = trim($_POST["nama"]);
|
||||||
|
$division = trim($_POST["division"]);
|
||||||
|
$mail = trim($_POST["mail"]);
|
||||||
|
$alamat = trim($_POST["alamat"]);
|
||||||
|
$picture = trim($_POST["picture"]);
|
||||||
|
|
||||||
|
|
||||||
|
$dsn = "mysql:host=$db_server;dbname=$db_name;charset=utf8mb4";
|
||||||
|
$options = [
|
||||||
|
PDO::ATTR_EMULATE_PREPARES => false, // turn off emulation mode for "real" prepared statements
|
||||||
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, //turn on errors in the form of exceptions
|
||||||
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, //make the default fetch be an associative array
|
||||||
|
];
|
||||||
|
try {
|
||||||
|
$pdo = new PDO($dsn, $db_user, $db_password, $options);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
error_log($e->getMessage());
|
||||||
|
exit('Something weird happened'); //something a user can understand
|
||||||
|
}
|
||||||
|
$stmt = $pdo->prepare("UPDATE data_karyawan SET created=?,idrfid=?,nama=?,division=?,mail=?,alamat=?,picture=? WHERE id=?");
|
||||||
|
|
||||||
|
|
||||||
|
if(!$stmt->execute([ $created,$idrfid,$nama,$division,$mail,$alamat,$picture,$id ])) {
|
||||||
|
echo "Something went wrong. Please try again later.";
|
||||||
|
header("location: error.php");
|
||||||
|
} else{
|
||||||
|
$stmt = null;
|
||||||
|
echo '<script language="javascript" type="text/javascript">
|
||||||
|
alert("Data berhasil dimutakhirkan");
|
||||||
|
window.location.replace("data_karyawan-index.php");
|
||||||
|
</script>';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Check existence of id parameter before processing further
|
||||||
|
if(isset($_GET["id"]) && !empty(trim($_GET["id"]))){
|
||||||
|
// Get URL parameter
|
||||||
|
$id = trim($_GET["id"]);
|
||||||
|
|
||||||
|
// Prepare a select statement
|
||||||
|
$sql = "SELECT * FROM data_karyawan WHERE id = ?";
|
||||||
|
if($stmt = mysqli_prepare($link, $sql)){
|
||||||
|
// Bind variables to the prepared statement as parameters
|
||||||
|
mysqli_stmt_bind_param($stmt, "i", $param_id);
|
||||||
|
|
||||||
|
// Set parameters
|
||||||
|
$param_id = $id;
|
||||||
|
|
||||||
|
// Attempt to execute the prepared statement
|
||||||
|
if(mysqli_stmt_execute($stmt)){
|
||||||
|
$result = mysqli_stmt_get_result($stmt);
|
||||||
|
|
||||||
|
if(mysqli_num_rows($result) == 1){
|
||||||
|
/* Fetch result row as an associative array. Since the result set
|
||||||
|
contains only one row, we don't need to use while loop */
|
||||||
|
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
|
||||||
|
|
||||||
|
// Retrieve individual field value
|
||||||
|
|
||||||
|
$created = $row["created"];
|
||||||
|
$idrfid = $row["idrfid"];
|
||||||
|
$nama = $row["nama"];
|
||||||
|
$division = $row["division"];
|
||||||
|
$mail = $row["mail"];
|
||||||
|
$alamat = $row["alamat"];
|
||||||
|
$picture = $row["picture"];
|
||||||
|
|
||||||
|
|
||||||
|
} else{
|
||||||
|
// URL doesn't contain valid id. Redirect to error page
|
||||||
|
header("location: error.php");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else{
|
||||||
|
echo "Oops! Something went wrong. Please try again later.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close statement
|
||||||
|
mysqli_stmt_close($stmt);
|
||||||
|
|
||||||
|
// Close connection
|
||||||
|
mysqli_close($link);
|
||||||
|
|
||||||
|
} else{
|
||||||
|
// URL doesn't contain id parameter. Redirect to error page
|
||||||
|
header("location: error.php");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
|
||||||
|
<title>PT. Mantap - Dashboard</title>
|
||||||
|
|
||||||
|
<!-- Custom fonts for this template-->
|
||||||
|
<link href="../src/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this template-->
|
||||||
|
<link href="../src/css/sb-admin-2.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this page -->
|
||||||
|
<link href="../src/vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body id="page-top">
|
||||||
|
|
||||||
|
<!-- Page Wrapper -->
|
||||||
|
<div id="wrapper">
|
||||||
|
|
||||||
|
<!-- Sidebar -->
|
||||||
|
<?php include 'partial_sidebar.php';?>
|
||||||
|
<!-- End of Sidebar -->
|
||||||
|
|
||||||
|
<!-- Content Wrapper -->
|
||||||
|
<div id="content-wrapper" class="d-flex flex-column">
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
|
<div id="content">
|
||||||
|
|
||||||
|
<!-- Topbar -->
|
||||||
|
<?php include 'partial_topbar.php';?>
|
||||||
|
<!-- End of Topbar -->
|
||||||
|
|
||||||
|
<!-- Begin Page Content -->
|
||||||
|
<div class="container-fluid">
|
||||||
|
|
||||||
|
<!-- Page Heading -->
|
||||||
|
<h1 class="h3 mb-2 text-gray-800">Data Karyawan</h1>
|
||||||
|
<div class="card shadow mb-4">
|
||||||
|
<div class="card-header py-3">
|
||||||
|
<h6 class="m-0 font-weight-bold text-primary">Tambah Data</h6>
|
||||||
|
</div>
|
||||||
|
<div class="card-body" >
|
||||||
|
<div class="col-md-12">
|
||||||
|
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="nama">Nama</label>
|
||||||
|
<input type="text" name="nama" class="form-control" value="<?php echo $nama; ?>" placeholder="Input nama karyawan" required>
|
||||||
|
<span class="help-block"><?php echo $nama_err; ?></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="idrfid">idrfid</label>
|
||||||
|
<input type="text" name="idrfid" class="form-control" value="<?php echo $idrfid; ?>" placeholder="Input idrfid kartu absensi" required>
|
||||||
|
<span class="help-block"><?php echo $idrfid_err; ?></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="mail">Email</label>
|
||||||
|
<input type="text" name="mail" class="form-control" value="<?php echo $mail; ?>" placeholder="Input email karyawan" required>
|
||||||
|
<span class="help-block"><?php echo $mail_err; ?></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="division">Divisi</label>
|
||||||
|
<select class="form-control" name="division">
|
||||||
|
<option value="Produksi" <?php if($division=="Produksi") echo 'selected="selected"'; ?> >Produksi</option>
|
||||||
|
<option value="Keuangan" <?php if($division=="Keuangan") echo 'selected="selected"'; ?> >Keuangan</option>
|
||||||
|
<option value="Perlengkapan" <?php if($division=="Perlengkapan") echo 'selected="selected"'; ?> >Perlengkapan</option>
|
||||||
|
<option value="Personalia" <?php if($division=="Personalia") echo 'selected="selected"'; ?> >Personalia</option>
|
||||||
|
<option value="Keteknikan" <?php if($division=="Keteknikan") echo 'selected="selected"'; ?> >Keteknikan</option>
|
||||||
|
</select>
|
||||||
|
<span class="help-block"><?php echo $division_err; ?></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="alamat">Alamat</label>
|
||||||
|
<textarea name="alamat" class="form-control" placeholder="Input alamat rumah karyawan"><?php echo $alamat ; ?></textarea>
|
||||||
|
<span class="help-block"><?php echo $alamat_err; ?></span>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="row justify-content-end">
|
||||||
|
<input type="hidden" name="created" value="<?php echo $created; ?>"/>
|
||||||
|
<input type="hidden" name="picture" value="<?php echo $picture; ?>"/>
|
||||||
|
<input type="hidden" name="id" value="<?php echo $id; ?>"/>
|
||||||
|
<input type="submit" class="btn btn-success" value="Edit">  
|
||||||
|
<a href="data_karyawan-index.php" class="btn btn-primary">Batal</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- /.container-fluid -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Main Content -->
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<footer class="sticky-footer bg-white">
|
||||||
|
<div class="container my-auto">
|
||||||
|
<div class="copyright text-center my-auto">
|
||||||
|
<span>Copyright © Arief HIdayatullah</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
<!-- End of Footer -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Content Wrapper -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Page Wrapper -->
|
||||||
|
|
||||||
|
<!-- Scroll to Top Button-->
|
||||||
|
<a class="scroll-to-top rounded" href="#page-top">
|
||||||
|
<i class="fas fa-angle-up"></i>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- Logout Modal-->
|
||||||
|
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="exampleModalLabel">Ready to Leave?</h5>
|
||||||
|
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">Select "Logout" below if you are ready to end your current session.</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||||
|
<a class="btn btn-primary" href="login.html">Logout</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Core plugin JavaScript-->
|
||||||
|
<script src="../src/vendor/jquery-easing/jquery.easing.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Custom scripts for all pages-->
|
||||||
|
<script src="../src/js/sb-admin-2.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Bootstrap core JavaScript-->
|
||||||
|
<script src="../src/vendor/jquery/jquery.min.js"></script>
|
||||||
|
<script src="../src/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,145 @@
|
||||||
|
<?php
|
||||||
|
date_default_timezone_set('Asia/Jakarta');
|
||||||
|
require_once "config.php";
|
||||||
|
|
||||||
|
|
||||||
|
$idrfid = "";
|
||||||
|
$nama = "";
|
||||||
|
$password = "";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$idrfid_err = "";
|
||||||
|
$nama_err = "";
|
||||||
|
$password_err = "";
|
||||||
|
|
||||||
|
|
||||||
|
if ($_SERVER["REQUEST_METHOD"] == "POST") {
|
||||||
|
|
||||||
|
$idrfid = trim($_POST["idrfid"]);
|
||||||
|
$nama = trim($_POST["nama"]);
|
||||||
|
$password = trim($_POST["password"]);
|
||||||
|
|
||||||
|
|
||||||
|
$dsn = "mysql:host=$db_server;dbname=$db_name;charset=utf8mb4";
|
||||||
|
$options = [
|
||||||
|
PDO::ATTR_EMULATE_PREPARES => false,
|
||||||
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$pdo = new PDO($dsn, $db_user, $db_password, $options);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
error_log($e->getMessage());
|
||||||
|
exit('Terjadi kesalahan');
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("SELECT id FROM data_registrasi WHERE idrfid = ?");
|
||||||
|
$stmt->execute([$idrfid]);
|
||||||
|
if ($stmt->rowCount() > 0) {
|
||||||
|
$idrfid_err = "ID RFID ini sudah terdaftar.";
|
||||||
|
} else {
|
||||||
|
$stmt = $pdo->prepare("INSERT INTO data_registrasi (idrfid, nama, password) VALUES (?, ?, ?)");
|
||||||
|
if ($stmt->execute([$idrfid, $nama, $password])) {
|
||||||
|
echo '<script language="javascript" type="text/javascript">
|
||||||
|
alert("Data berhasil ditambahkan");
|
||||||
|
window.location.replace("data_registrasi.php");
|
||||||
|
</script>';
|
||||||
|
} else {
|
||||||
|
echo "Terjadi kesalahan. Silakan coba lagi nanti.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<title>PT. Mantap - Dashboard</title>
|
||||||
|
<link href="../src/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||||
|
<link href="../src/css/sb-admin-2.min.css" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
.error-message { color: red; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body id="page-top">
|
||||||
|
<div id="wrapper">
|
||||||
|
<?php include 'partial_sidebar.php';?>
|
||||||
|
<div id="content-wrapper" class="d-flex flex-column">
|
||||||
|
<div id="content">
|
||||||
|
<?php include 'partial_topbar.php';?>
|
||||||
|
<div class="container-fluid">
|
||||||
|
<h1 class="h3 mb-2 text-gray-800">Data Karyawan</h1>
|
||||||
|
<div class="card shadow mb-4">
|
||||||
|
<div class="card-header py-3">
|
||||||
|
<h6 class="m-0 font-weight-bold text-primary">Tambah Data</h6>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="nama">Nama</label>
|
||||||
|
<input type="text" name="nama" class="form-control" value="<?php echo $nama; ?>" placeholder="Input nama karyawan" required>
|
||||||
|
<span class="help-block"><?php echo $nama_err; ?></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="idrfid">ID RFID</label>
|
||||||
|
<input type="text" name="idrfid" class="form-control" value="<?php echo $idrfid; ?>" placeholder="Input ID RFID kartu absensi" required>
|
||||||
|
<span class="error-message"><?php echo $idrfid_err; ?></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="password">Password</label>
|
||||||
|
<input type="password" name="password" class="form-control" value="<?php echo $password; ?>" placeholder="Input password karyawan" required>
|
||||||
|
<span class="help-block"><?php echo $password_err; ?></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="row justify-content-end">
|
||||||
|
<input type="submit" class="btn btn-success" value="Tambah">  
|
||||||
|
<a href="data_registrasi.php" class="btn btn-primary">Batal</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer class="sticky-footer bg-white">
|
||||||
|
<div class="container my-auto">
|
||||||
|
<div class="copyright text-center my-auto">
|
||||||
|
<span>Copyright © Arief Hidayatullah</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a class="scroll-to-top rounded" href="#page-top">
|
||||||
|
<i class="fas fa-angle-up"></i>
|
||||||
|
</a>
|
||||||
|
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="exampleModalLabel">Siap untuk keluar?</h5>
|
||||||
|
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">Pilih "Logout" di bawah jika Anda siap mengakhiri sesi Anda saat ini.</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-secondary" type="button" data-dismiss="modal">Batal</button>
|
||||||
|
<a class="btn btn-primary" href="login.html">Logout</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="../src/vendor/jquery-easing/jquery.easing.min.js"></script>
|
||||||
|
<script src="../src/js/sb-admin-2.min.js"></script>
|
||||||
|
<script src="../src/vendor/jquery/jquery.min.js"></script>
|
||||||
|
<script src="../src/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
// Process delete operation after confirmation
|
||||||
|
if(isset($_POST["id"]) && !empty($_POST["id"])){
|
||||||
|
// Include config file
|
||||||
|
require_once "config.php";
|
||||||
|
|
||||||
|
// Prepare a delete statement
|
||||||
|
$sql = "DELETE FROM data_registrasi WHERE id = ?";
|
||||||
|
|
||||||
|
if($stmt = mysqli_prepare($link, $sql)){
|
||||||
|
// Bind variables to the prepared statement as parameters
|
||||||
|
mysqli_stmt_bind_param($stmt, "i", $param_id);
|
||||||
|
|
||||||
|
// Set parameters
|
||||||
|
$param_id = trim($_POST["id"]);
|
||||||
|
|
||||||
|
// Attempt to execute the prepared statement
|
||||||
|
if(mysqli_stmt_execute($stmt)){
|
||||||
|
// Records deleted successfully. Redirect to landing page
|
||||||
|
echo '<script language="javascript" type="text/javascript">
|
||||||
|
alert("Data berhasil dihapus");
|
||||||
|
window.location.replace("data_registrasi.php");
|
||||||
|
</script>';
|
||||||
|
exit();
|
||||||
|
} else{
|
||||||
|
echo "Oops! Something went wrong. Please try again later.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close statement
|
||||||
|
mysqli_stmt_close($stmt);
|
||||||
|
|
||||||
|
// Close connection
|
||||||
|
mysqli_close($link);
|
||||||
|
} else{
|
||||||
|
// Check existence of id parameter
|
||||||
|
if(empty(trim($_GET["id"]))){
|
||||||
|
// URL doesn't contain id parameter. Redirect to error page
|
||||||
|
header("location: error.php");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
@ -0,0 +1,184 @@
|
||||||
|
<?php
|
||||||
|
// Check existence of id parameter before processing further
|
||||||
|
if(isset($_GET["id"]) && !empty(trim($_GET["id"]))){
|
||||||
|
// Include config file
|
||||||
|
require_once "config.php";
|
||||||
|
|
||||||
|
// Prepare a select statement
|
||||||
|
$sql = "SELECT * FROM data_registrasi WHERE id = ?";
|
||||||
|
|
||||||
|
if($stmt = mysqli_prepare($link, $sql)){
|
||||||
|
// Bind variables to the prepared statement as parameters
|
||||||
|
mysqli_stmt_bind_param($stmt, "i", $param_id);
|
||||||
|
|
||||||
|
// Set parameters
|
||||||
|
$param_id = trim($_GET["id"]);
|
||||||
|
|
||||||
|
// Attempt to execute the prepared statement
|
||||||
|
if(mysqli_stmt_execute($stmt)){
|
||||||
|
$result = mysqli_stmt_get_result($stmt);
|
||||||
|
|
||||||
|
if(mysqli_num_rows($result) == 1){
|
||||||
|
/* Fetch result row as an associative array. Since the result set
|
||||||
|
contains only one row, we don't need to use while loop */
|
||||||
|
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
|
||||||
|
|
||||||
|
/* Retrieve individual field value
|
||||||
|
{INDIVIDUAL_FIELDS}
|
||||||
|
$name = $row["name"];
|
||||||
|
$address = $row["address"];
|
||||||
|
$salary = $row["salary"];
|
||||||
|
*/
|
||||||
|
} else{
|
||||||
|
// URL doesn't contain valid id parameter. Redirect to error page
|
||||||
|
header("location: error.php");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else{
|
||||||
|
echo "Oops! Something went wrong. Please try again later.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close statement
|
||||||
|
mysqli_stmt_close($stmt);
|
||||||
|
|
||||||
|
// Close connection
|
||||||
|
mysqli_close($link);
|
||||||
|
} else{
|
||||||
|
// URL doesn't contain id parameter. Redirect to error page
|
||||||
|
header("location: error.php");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
|
||||||
|
<title>PT. Mantap - Dashboard</title>
|
||||||
|
|
||||||
|
<!-- Custom fonts for this template-->
|
||||||
|
<link href="../src/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this template-->
|
||||||
|
<link href="../src/css/sb-admin-2.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this page -->
|
||||||
|
<link href="../src/vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body id="page-top">
|
||||||
|
|
||||||
|
<!-- Page Wrapper -->
|
||||||
|
<div id="wrapper">
|
||||||
|
|
||||||
|
<!-- Sidebar -->
|
||||||
|
<?php include 'partial_sidebar.php';?>
|
||||||
|
<!-- End of Sidebar -->
|
||||||
|
|
||||||
|
<!-- Content Wrapper -->
|
||||||
|
<div id="content-wrapper" class="d-flex flex-column">
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
|
<div id="content">
|
||||||
|
|
||||||
|
<!-- Topbar -->
|
||||||
|
<?php include 'partial_topbar.php';?>
|
||||||
|
<!-- End of Topbar -->
|
||||||
|
|
||||||
|
<!-- Begin Page Content -->
|
||||||
|
<div class="container-fluid">
|
||||||
|
|
||||||
|
<!-- Page Heading -->
|
||||||
|
<h1 class="h3 mb-2 text-gray-800">Data Karyawan</h1>
|
||||||
|
<div class="card shadow mb-4">
|
||||||
|
<div class="card-header py-3">
|
||||||
|
<h6 class="m-0 font-weight-bold text-primary">Hapus Data</h6>
|
||||||
|
</div>
|
||||||
|
<div class="card-body" >
|
||||||
|
<div class="col-md-12 ">
|
||||||
|
<form action="data_registrasi-delete-ok.php" method="post">
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
<p>Apakah anda ingin menghapus data <b><?php echo $row["nama"]; ?></b> ?</p><br>
|
||||||
|
</div>
|
||||||
|
<input type="hidden" name="id" value="<?php echo $row["id"]; ?>"/>
|
||||||
|
<hr>
|
||||||
|
<div class="row justify-content-end">
|
||||||
|
<input type="submit" value="Ya" class="btn btn-danger">  
|
||||||
|
<a href="data_registrasi.php" class="btn btn-primary">Batal</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- /.container-fluid -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Main Content -->
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<footer class="sticky-footer bg-white">
|
||||||
|
<div class="container my-auto">
|
||||||
|
<div class="copyright text-center my-auto">
|
||||||
|
<span>Copyright © Arief HIdayatullah</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
<!-- End of Footer -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Content Wrapper -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Page Wrapper -->
|
||||||
|
|
||||||
|
<!-- Scroll to Top Button-->
|
||||||
|
<a class="scroll-to-top rounded" href="#page-top">
|
||||||
|
<i class="fas fa-angle-up"></i>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- Logout Modal-->
|
||||||
|
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="exampleModalLabel">Ready to Leave?</h5>
|
||||||
|
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">Select "Logout" below if you are ready to end your current session.</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||||
|
<a class="btn btn-primary" href="login.html">Logout</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Bootstrap core JavaScript-->
|
||||||
|
<script src="../src/vendor/jquery/jquery.min.js"></script>
|
||||||
|
<script src="../src/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Custom scripts for all pages-->
|
||||||
|
<script src="../src/js/sb-admin-2.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,291 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
|
||||||
|
<title>R-collection Dashboard</title>
|
||||||
|
|
||||||
|
<!-- Custom fonts for this template-->
|
||||||
|
<link href="../src/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this template-->
|
||||||
|
<link href="../src/css/sb-admin-2.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this page -->
|
||||||
|
<link href="../src/vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Bootstrap core JavaScript-->
|
||||||
|
<script src="../src/vendor/jquery/jquery.min.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(document).ready(function(){
|
||||||
|
$("#idrfid").on('blur', function(){
|
||||||
|
var idrfid = $(this).val();
|
||||||
|
if(idrfid != ""){
|
||||||
|
$.ajax({
|
||||||
|
url: "check_rfid.php",
|
||||||
|
method: "POST",
|
||||||
|
data: {idrfid: idrfid},
|
||||||
|
success: function(response){
|
||||||
|
if(response != '0'){
|
||||||
|
$("#rfid-error").show();
|
||||||
|
$("#idrfid").val('');
|
||||||
|
} else {
|
||||||
|
$("#rfid-error").hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body id="page-top">
|
||||||
|
|
||||||
|
<!-- Page Wrapper -->
|
||||||
|
<div id="wrapper">
|
||||||
|
|
||||||
|
<!-- Sidebar -->
|
||||||
|
<?php include 'partial_sidebar.php';?>
|
||||||
|
<!-- End of Sidebar -->
|
||||||
|
|
||||||
|
<!-- Content Wrapper -->
|
||||||
|
<div id="content-wrapper" class="d-flex flex-column">
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
|
<div id="content">
|
||||||
|
|
||||||
|
<!-- Topbar -->
|
||||||
|
<?php include 'partial_topbar.php';?>
|
||||||
|
<!-- End of Topbar -->
|
||||||
|
|
||||||
|
<!-- Begin Page Content -->
|
||||||
|
<div class="container-fluid">
|
||||||
|
|
||||||
|
<!-- Page Heading -->
|
||||||
|
<h1 class="h3 mb-2 text-gray-800">Data Akun Karyawan</h1>
|
||||||
|
|
||||||
|
<!-- DataTales Example -->
|
||||||
|
<div class="card shadow mb-4">
|
||||||
|
<div class="card-header py-3">
|
||||||
|
<h6 class="m-0 font-weight-bold text-primary">Data Akun Aktif</h6>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<a href="data_registrasi-create.php" class="btn btn-success pull-right">Tambah Data Baru</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Form tambah data -->
|
||||||
|
<div class="modal fade" id="tambahDataModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="exampleModalLabel">Tambah Data Karyawan</h5>
|
||||||
|
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form action="simpan_data.php" method="post">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="idrfid">IDRFID/Username:</label>
|
||||||
|
<input type="text" class="form-control" id="idrfid" name="idrfid" required>
|
||||||
|
<span id="rfid-error" style="color: red; display: none;">IDRFID ini sudah digunakan.</span>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="nama">Nama:</label>
|
||||||
|
<input type="text" class="form-control" id="nama" name="nama">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password">Password:</label>
|
||||||
|
<input type="password" class="form-control" id="password" name="password">
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// Include config file
|
||||||
|
require_once "config.php";
|
||||||
|
|
||||||
|
//Pagination
|
||||||
|
if (isset($_GET['pageno'])) {
|
||||||
|
$pageno = $_GET['pageno'];
|
||||||
|
} else {
|
||||||
|
$pageno = 1;
|
||||||
|
}
|
||||||
|
$no_of_records_per_page = 10;
|
||||||
|
$offset = ($pageno - 1) * $no_of_records_per_page;
|
||||||
|
|
||||||
|
$total_pages_sql = "SELECT COUNT(*) FROM data_registrasi";
|
||||||
|
$result = mysqli_query($link, $total_pages_sql);
|
||||||
|
$total_rows = mysqli_fetch_array($result)[0];
|
||||||
|
$total_pages = ceil($total_rows / $no_of_records_per_page);
|
||||||
|
|
||||||
|
//Column sorting on column name
|
||||||
|
$orderBy = array('nama', 'idrfid', 'password');
|
||||||
|
$order = 'id';
|
||||||
|
if (isset($_GET['order']) && in_array($_GET['order'], $orderBy)) {
|
||||||
|
$order = $_GET['order'];
|
||||||
|
}
|
||||||
|
|
||||||
|
//Column sort order
|
||||||
|
$sortBy = array('asc', 'desc');
|
||||||
|
$sort = 'desc';
|
||||||
|
if (isset($_GET['sort']) && in_array($_GET['sort'], $sortBy)) {
|
||||||
|
if ($_GET['sort'] == 'asc') {
|
||||||
|
$sort = 'desc';
|
||||||
|
} else {
|
||||||
|
$sort = 'asc';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt select query execution
|
||||||
|
$sql = "SELECT * FROM data_registrasi ORDER BY $order $sort LIMIT $offset, $no_of_records_per_page";
|
||||||
|
|
||||||
|
if (!empty($_GET['search'])) {
|
||||||
|
$search = ($_GET['search']);
|
||||||
|
$sql = "SELECT * FROM data_registrasi
|
||||||
|
WHERE CONCAT(nama, idrfid, password)
|
||||||
|
LIKE '%$search%' COLLATE utf8mb4_general_ci
|
||||||
|
ORDER BY $order $sort
|
||||||
|
LIMIT $offset, $no_of_records_per_page";
|
||||||
|
} else {
|
||||||
|
$search = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($result = mysqli_query($link, $sql)) {
|
||||||
|
if (mysqli_num_rows($result) > 0) {
|
||||||
|
echo "<table class='table table-bordered table-striped'>";
|
||||||
|
echo "<thead>";
|
||||||
|
echo "<tr>";
|
||||||
|
echo "<th><a href=?search=$search&sort=&order=nama&sort=$sort>Nama</a></th>";
|
||||||
|
echo "<th><a href=data_register-create.php search=$search&sort=&order=idrfid&sort=$sort>IDRFID/Username</a></th>";
|
||||||
|
echo "<th><a href=data_register-create.php search=$search&sort=&order=password&sort=$sort>Password</a></th>";
|
||||||
|
echo "<th>Action</th>";
|
||||||
|
echo "</tr>";
|
||||||
|
echo "</thead>";
|
||||||
|
echo "<tbody>";
|
||||||
|
while ($row = mysqli_fetch_array($result)) {
|
||||||
|
echo "<tr>";
|
||||||
|
echo "<td>" . $row['nama'] . "</td>";
|
||||||
|
echo "<td>" . $row['idrfid'] . "</td>";
|
||||||
|
echo "<td>" . $row['password'] . "</td>";
|
||||||
|
echo "<td>";
|
||||||
|
echo "<a href='data_registrasi-delete.php?id=" . $row['id'] . "' title='Hapus' data-toggle='tooltip'><span class='fa fa-trash'></span></a>";
|
||||||
|
echo "</td>";
|
||||||
|
echo "</tr>";
|
||||||
|
}
|
||||||
|
echo "</tbody>";
|
||||||
|
echo "</table>";
|
||||||
|
?>
|
||||||
|
<nav aria-label="Page navigation example">
|
||||||
|
<ul class="pagination">
|
||||||
|
<li class="page-item"><a class="page-link" href="?pageno=1">First</a></li>
|
||||||
|
<li class="page-item <?php if ($pageno <= 1) { echo 'disabled'; } ?>">
|
||||||
|
<a class="page-link" href="<?php if ($pageno <= 1) { echo '#'; } else { echo "?pageno=" . ($pageno - 1); } ?>">Prev</a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item <?php if ($pageno >= $total_pages) { echo 'disabled'; } ?>">
|
||||||
|
<a class="page-link" href="<?php if ($pageno >= $total_pages) { echo '#'; } else { echo "?pageno=" . ($pageno + 1); } ?>">Next</a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item"><a class="page-link" href="?pageno=<?php echo $total_pages; ?>">Last</a></li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<?php
|
||||||
|
// Free result set
|
||||||
|
mysqli_free_result($result);
|
||||||
|
} else {
|
||||||
|
echo "<p class='lead'><em>No records were found.</em></p>";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo "ERROR: Could not able to execute $sql. " . mysqli_error($link);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close connection
|
||||||
|
mysqli_close($link);
|
||||||
|
?>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- /.container-fluid -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Main Content -->
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<footer class="sticky-footer bg-white">
|
||||||
|
<div class="container my-auto">
|
||||||
|
<div class="copyright text-center my-auto">
|
||||||
|
<span>Copyright © Arief HIdayatullah</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
<!-- End of Footer -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Content Wrapper -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Page Wrapper -->
|
||||||
|
|
||||||
|
<!-- Scroll to Top Button-->
|
||||||
|
<a class="scroll-to-top rounded" href="#page-top">
|
||||||
|
<i class="fas fa-angle-up"></i>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- Logout Modal-->
|
||||||
|
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="exampleModalLabel">Ready to Leave?</h5>
|
||||||
|
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">Select "Logout" below if you are ready to end your current session.</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||||
|
<a class="btn btn-primary" href="http://localhost/rfidcam/">Logout</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Page level plugins -->
|
||||||
|
<script src="../src/vendor/datatables/jquery.dataTables.min.js"></script>
|
||||||
|
<script src="../src/vendor/datatables/dataTables.bootstrap4.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Custom scripts for all pages-->
|
||||||
|
<script src="../src/js/sb-admin-2.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
|
||||||
|
<title>PT. Mantap - Dashboard</title>
|
||||||
|
|
||||||
|
<!-- Custom fonts for this template-->
|
||||||
|
<link href="../src/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this template-->
|
||||||
|
<link href="../src/css/sb-admin-2.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this page -->
|
||||||
|
<link href="../src/vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body id="page-top">
|
||||||
|
|
||||||
|
<!-- Page Wrapper -->
|
||||||
|
<div id="wrapper">
|
||||||
|
|
||||||
|
<!-- Sidebar -->
|
||||||
|
<?php include 'partial_sidebar.php';?>
|
||||||
|
<!-- End of Sidebar -->
|
||||||
|
|
||||||
|
<!-- Content Wrapper -->
|
||||||
|
<div id="content-wrapper" class="d-flex flex-column">
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
|
<div id="content">
|
||||||
|
|
||||||
|
<!-- Topbar -->
|
||||||
|
<?php include 'partial_topbar.php';?>
|
||||||
|
<!-- End of Topbar -->
|
||||||
|
|
||||||
|
<!-- Begin Page Content -->
|
||||||
|
<div class="container-fluid">
|
||||||
|
|
||||||
|
<!-- 404 Error Text -->
|
||||||
|
<div class="text-center">
|
||||||
|
<div class="error mx-auto" data-text="404">404</div>
|
||||||
|
<p class="lead text-gray-800 mb-5">Page Not Found</p>
|
||||||
|
<p class="text-gray-500 mb-0">It looks like you found a glitch in the matrix...</p>
|
||||||
|
<a href="index.php">← Back to Dashboard</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- /.container-fluid -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Main Content -->
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<footer class="sticky-footer bg-white">
|
||||||
|
<div class="container my-auto">
|
||||||
|
<div class="copyright text-center my-auto">
|
||||||
|
<span>Copyright © Arief HIdayatullah</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
<!-- End of Footer -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Content Wrapper -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Page Wrapper -->
|
||||||
|
|
||||||
|
<!-- Scroll to Top Button-->
|
||||||
|
<a class="scroll-to-top rounded" href="#page-top">
|
||||||
|
<i class="fas fa-angle-up"></i>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- Logout Modal-->
|
||||||
|
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="exampleModalLabel">Ready to Leave?</h5>
|
||||||
|
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">Select "Logout" below if you are ready to end your current session.</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||||
|
<a class="btn btn-primary" href="login.html">Logout</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Bootstrap core JavaScript-->
|
||||||
|
<script src="../src/vendor/jquery/jquery.min.js"></script>
|
||||||
|
<script src="../src/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<!-- Custom scripts for all pages-->
|
||||||
|
<script src="../src/js/sb-admin-2.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?php require 'config.php'; ?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Export To Excel</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<form action="export.php" method="POST">
|
||||||
|
<label for="search">Cari Karyawan:</label> <!-- Ubah id dan name menjadi search -->
|
||||||
|
<input type="text" name="search" id="search" placeholder="Masukkan Nama Karyawan">
|
||||||
|
|
||||||
|
<label for="start_date">Tanggal Awal:</label>
|
||||||
|
<input type="date" name="start_date" id="start_date">
|
||||||
|
|
||||||
|
<label for="end_date">Tanggal Akhir:</label>
|
||||||
|
<input type="date" name="end_date" id="end_date">
|
||||||
|
|
||||||
|
<button type="submit" name="submit">Export To Excel</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<?php require 'data.php'; ?>
|
||||||
|
|
||||||
|
<a href="data_absen-index.php"> <button type="button" name="button">Kembali</button> </a>
|
||||||
|
<hr>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,122 @@
|
||||||
|
<?php
|
||||||
|
require 'config.php';
|
||||||
|
|
||||||
|
// Periksa apakah tombol submit ditekan
|
||||||
|
if (isset($_POST['submit'])) {
|
||||||
|
$start_date = $_POST['start_date'];
|
||||||
|
$end_date = $_POST['end_date'];
|
||||||
|
$search = $_POST['search']; // Ambil nilai dari input search
|
||||||
|
|
||||||
|
// Buat header untuk mengatur tipe konten dan nama file
|
||||||
|
header("Content-Type: application/vnd.ms-excel");
|
||||||
|
header("Content-Disposition: attachment; filename=Rekap_Absensi_".$start_date."_to_".$end_date.".xls");
|
||||||
|
|
||||||
|
// Buat tabel HTML yang akan diubah menjadi file Excel
|
||||||
|
echo '<table border="1" cellpadding="10" cellspacing="5">
|
||||||
|
<tr>
|
||||||
|
<td>#</td>
|
||||||
|
<td>created</td>
|
||||||
|
<td>idrfid</td>
|
||||||
|
<td>nama</td>
|
||||||
|
<td>division</td>
|
||||||
|
<td>mail</td>
|
||||||
|
<td>alamat</td>
|
||||||
|
<td>tgl</td>
|
||||||
|
<td>jam masuk</td>
|
||||||
|
<td>jam keluar</td>
|
||||||
|
<td>Action</td>
|
||||||
|
</tr>';
|
||||||
|
|
||||||
|
$i = 1;
|
||||||
|
$query = "SELECT k.*, a.tgl, a.rekap_masuk, a.rekap_keluar
|
||||||
|
FROM data_karyawan k
|
||||||
|
INNER JOIN data_absen a ON k.idrfid = a.idrfid
|
||||||
|
WHERE a.tgl BETWEEN '$start_date' AND '$end_date'";
|
||||||
|
|
||||||
|
// Tambahkan kondisi pencarian karyawan jika ada
|
||||||
|
if (!empty($search)) {
|
||||||
|
$query .= " AND k.nama LIKE '%$search%'";
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows = mysqli_query($conn, $query);
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
// Tentukan tindakan berdasarkan keterlambatan masuk atau keluar lebih awal
|
||||||
|
$action = '';
|
||||||
|
$jamMasukLimit = '09:00:00';
|
||||||
|
$jamKeluarLimit = '16:00:00';
|
||||||
|
$terlambat = $row["rekap_masuk"] > $jamMasukLimit;
|
||||||
|
$pulangDulu = $row["rekap_keluar"] < $jamKeluarLimit;
|
||||||
|
|
||||||
|
if ($terlambat && $pulangDulu) {
|
||||||
|
$action = 'Terlambat dan Pulang Dulu';
|
||||||
|
} elseif ($terlambat) {
|
||||||
|
$action = 'Terlambat';
|
||||||
|
} elseif ($pulangDulu) {
|
||||||
|
$action = 'Pulang Dulu';
|
||||||
|
} else {
|
||||||
|
$action = 'Tidak Terlambat';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '<tr>
|
||||||
|
<td>' . $i++ . '</td>
|
||||||
|
<td>' . $row["created"] . '</td>
|
||||||
|
<td>' . $row["idrfid"] . '</td>
|
||||||
|
<td>' . $row["nama"] . '</td>
|
||||||
|
<td>' . $row["division"] . '</td>
|
||||||
|
<td>' . $row["mail"] . '</td>
|
||||||
|
<td>' . $row["alamat"] . '</td>
|
||||||
|
<td>' . $row["tgl"] . '</td>
|
||||||
|
<td class="jam-masuk">' . $row["rekap_masuk"] . '</td>
|
||||||
|
<td class="jam-keluar">' . $row["rekap_keluar"] . '</td>
|
||||||
|
<td>' . $action . '</td>
|
||||||
|
</tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '</table>';
|
||||||
|
echo '<br><br>';
|
||||||
|
|
||||||
|
// Query untuk rekapitulasi absensi
|
||||||
|
$query_rekap = "SELECT k.nama,
|
||||||
|
SUM(CASE WHEN a.rekap_masuk <= '09:00:00' AND a.rekap_keluar >= '16:00:00' THEN 1 ELSE 0 END) AS tidak_terlambat,
|
||||||
|
SUM(CASE WHEN a.rekap_masuk > '09:00:00' THEN 1 ELSE 0 END) AS terlambat,
|
||||||
|
SUM(CASE WHEN a.rekap_keluar < '16:00:00' THEN 1 ELSE 0 END) AS pulang_dulu,
|
||||||
|
SUM(CASE WHEN a.rekap_masuk > '09:00:00' AND a.rekap_keluar < '16:00:00' THEN 1 ELSE 0 END) AS terlambat_dan_pulang_dulu
|
||||||
|
FROM data_karyawan k
|
||||||
|
INNER JOIN data_absen a ON k.idrfid = a.idrfid
|
||||||
|
WHERE a.tgl BETWEEN '$start_date' AND '$end_date'";
|
||||||
|
|
||||||
|
// Tambahkan kondisi pencarian karyawan jika ada
|
||||||
|
if (!empty($search)) {
|
||||||
|
$query_rekap .= " AND k.nama LIKE '%$search%'";
|
||||||
|
}
|
||||||
|
|
||||||
|
$query_rekap .= " GROUP BY k.nama ORDER BY k.nama";
|
||||||
|
|
||||||
|
$rows_rekap = mysqli_query($conn, $query_rekap);
|
||||||
|
|
||||||
|
echo '<table border="1" cellpadding="10" cellspacing="5">
|
||||||
|
<tr>
|
||||||
|
<td>Nama</td>
|
||||||
|
<td>Tidak Terlambat</td>
|
||||||
|
<td>Terlambat</td>
|
||||||
|
<td>Pulang Dulu</td>
|
||||||
|
<td>Terlambat dan Pulang Dulu</td>
|
||||||
|
</tr>';
|
||||||
|
|
||||||
|
foreach ($rows_rekap as $row_rekap) {
|
||||||
|
echo '<tr>
|
||||||
|
<td>' . $row_rekap["nama"] . '</td>
|
||||||
|
<td>' . $row_rekap["tidak_terlambat"] . '</td>
|
||||||
|
<td>' . $row_rekap["terlambat"] . '</td>
|
||||||
|
<td>' . $row_rekap["pulang_dulu"] . '</td>
|
||||||
|
<td>' . $row_rekap["terlambat_dan_pulang_dulu"] . '</td>
|
||||||
|
</tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '</table>';
|
||||||
|
} else {
|
||||||
|
// Redirect ke halaman lain jika tombol submit tidak ditekan
|
||||||
|
header("Location: index.php");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
@ -0,0 +1,392 @@
|
||||||
|
<?php
|
||||||
|
// Include config file
|
||||||
|
require_once "config.php";
|
||||||
|
|
||||||
|
// Prepare a delete statement
|
||||||
|
$sql = "SELECT * FROM data_karyawan";
|
||||||
|
|
||||||
|
if($stmt = mysqli_prepare($link, $sql)){
|
||||||
|
// Attempt to execute the prepared statement
|
||||||
|
if(mysqli_stmt_execute($stmt)){
|
||||||
|
$result = mysqli_stmt_get_result($stmt);
|
||||||
|
$rowcount=mysqli_num_rows($result);
|
||||||
|
}else{
|
||||||
|
$rowcount = "null";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$today = date("Y-m-d");
|
||||||
|
$sql = "SELECT data_absen.idrfid, tgl, nama, division,
|
||||||
|
min(case when status1='IN' then rekap_masuk end) jam_masuk,
|
||||||
|
max(CASE WHEN status2='OUT' then rekap_keluar end) jam_keluar
|
||||||
|
FROM data_absen, data_karyawan
|
||||||
|
WHERE data_absen.idrfid=data_karyawan.idrfid AND tgl='".$today."'
|
||||||
|
GROUP BY data_absen.idrfid";
|
||||||
|
|
||||||
|
if($stmt = mysqli_prepare($link, $sql)){
|
||||||
|
//mysqli_stmt_bind_param($stmt, "i", $today );
|
||||||
|
// Attempt to execute the prepared statement
|
||||||
|
if(mysqli_stmt_execute($stmt)){
|
||||||
|
$result = mysqli_stmt_get_result($stmt);
|
||||||
|
$absensi =mysqli_num_rows($result);
|
||||||
|
}else{
|
||||||
|
$absensi = "null";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "SELECT * FROM data_invalid GROUP BY idrfid";
|
||||||
|
if($stmt = mysqli_prepare($link, $sql)){
|
||||||
|
//mysqli_stmt_bind_param($stmt, "i", $today );
|
||||||
|
// Attempt to execute the prepared statement
|
||||||
|
if(mysqli_stmt_execute($stmt)){
|
||||||
|
$result = mysqli_stmt_get_result($stmt);
|
||||||
|
$invalid =mysqli_num_rows($result);
|
||||||
|
}else{
|
||||||
|
$invalid = "null";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Close statement
|
||||||
|
mysqli_stmt_close($stmt);
|
||||||
|
|
||||||
|
// Close connection
|
||||||
|
mysqli_close($link);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
|
||||||
|
<title>R-collection Dashboard</title>
|
||||||
|
|
||||||
|
<!-- Custom fonts for this template-->
|
||||||
|
<link href="../src/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Custom styles for this template-->
|
||||||
|
<link href="../src/css/sb-admin-2.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body id="page-top">
|
||||||
|
|
||||||
|
<!-- Page Wrapper -->
|
||||||
|
<div id="wrapper">
|
||||||
|
|
||||||
|
<!-- Sidebar -->
|
||||||
|
<?php include 'partial_sidebar.php';?>
|
||||||
|
<!-- End of Sidebar -->
|
||||||
|
|
||||||
|
<!-- Content Wrapper -->
|
||||||
|
<div id="content-wrapper" class="d-flex flex-column">
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
|
<div id="content">
|
||||||
|
|
||||||
|
<!-- Topbar -->
|
||||||
|
<?php include 'partial_topbar.php';?>
|
||||||
|
<!-- End of Topbar -->
|
||||||
|
|
||||||
|
<!-- Begin Page Content -->
|
||||||
|
<div class="container-fluid">
|
||||||
|
|
||||||
|
<!-- Page Heading -->
|
||||||
|
<div class="d-sm-flex align-items-center justify-content-between mb-4">
|
||||||
|
<h1 class="h3 mb-0 text-gray-800">Dashboard</h1>
|
||||||
|
<!-- <a href="#" class="d-none d-sm-inline-block btn btn-sm btn-primary shadow-sm"><i class="fas fa-download fa-sm text-white-50"></i> Generate Report</a> -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Content Row -->
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<!-- Earnings (Monthly) Card Example -->
|
||||||
|
<div class="col-xl-3 col-md-6 mb-4">
|
||||||
|
<div class="card border-left-primary shadow h-100 py-2">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row no-gutters align-items-center">
|
||||||
|
<div class="col mr-2">
|
||||||
|
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">Total Karyawan</div>
|
||||||
|
<div class="h5 mb-0 font-weight-bold text-gray-800"><?php echo $rowcount; ?></div>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
|
<i class="fas fa-calendar fa-2x text-gray-300"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Earnings (Monthly) Card Example -->
|
||||||
|
<div class="col-xl-3 col-md-6 mb-4">
|
||||||
|
<div class="card border-left-success shadow h-100 py-2">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row no-gutters align-items-center">
|
||||||
|
<div class="col mr-2">
|
||||||
|
<div class="text-xs font-weight-bold text-success text-uppercase mb-1">Absensi Hari ini</div>
|
||||||
|
<div class="h5 mb-0 font-weight-bold text-gray-800"><?php echo $absensi; ?></div>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
|
<i class="fas fa-user fa-2x text-gray-300"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Earnings (Monthly) Card Example -->
|
||||||
|
<!-- <div class="col-xl-3 col-md-6 mb-4">
|
||||||
|
<div class="card border-left-info shadow h-100 py-2">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row no-gutters align-items-center">
|
||||||
|
<div class="col mr-2">
|
||||||
|
<div class="text-xs font-weight-bold text-info text-uppercase mb-1">Tasks</div>
|
||||||
|
<div class="row no-gutters align-items-center">
|
||||||
|
<div class="col-auto">
|
||||||
|
<div class="h5 mb-0 mr-3 font-weight-bold text-gray-800">50%</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="progress progress-sm mr-2">
|
||||||
|
<div class="progress-bar bg-info" role="progressbar" style="width: 50%" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
|
<i class="fas fa-clipboard-list fa-2x text-gray-300"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
<!-- Pending Requests Card Example -->
|
||||||
|
<div class="col-xl-3 col-md-6 mb-4">
|
||||||
|
<div class="card border-left-warning shadow h-100 py-2">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row no-gutters align-items-center">
|
||||||
|
<div class="col mr-2">
|
||||||
|
<div class="text-xs font-weight-bold text-warning text-uppercase mb-1">Kartu Invalid</div>
|
||||||
|
<div class="h5 mb-0 font-weight-bold text-gray-800"><?php echo $invalid; ?></div>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
|
<i class="fas fa-stop-circle fa-2x text-gray-300"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Content Row -->
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<!-- Area Chart -->
|
||||||
|
<!-- <div class="col-xl-8 col-lg-7">
|
||||||
|
<div class="card shadow mb-4"> -->
|
||||||
|
<!-- Card Header - Dropdown -->
|
||||||
|
<!-- <div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||||
|
<h6 class="m-0 font-weight-bold text-primary">Earnings Overview</h6>
|
||||||
|
<div class="dropdown no-arrow">
|
||||||
|
<a class="dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
<i class="fas fa-ellipsis-v fa-sm fa-fw text-gray-400"></i>
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-menu dropdown-menu-right shadow animated--fade-in" aria-labelledby="dropdownMenuLink">
|
||||||
|
<div class="dropdown-header">Dropdown Header:</div>
|
||||||
|
<a class="dropdown-item" href="#">Action</a>
|
||||||
|
<a class="dropdown-item" href="#">Another action</a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<a class="dropdown-item" href="#">Something else here</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
<!-- Card Body -->
|
||||||
|
<!-- <div class="card-body">
|
||||||
|
<div class="chart-area">
|
||||||
|
<canvas id="myAreaChart"></canvas>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Pie Chart -->
|
||||||
|
<div class="col-xl-4 col-lg-5">
|
||||||
|
<div class="card shadow mb-4">
|
||||||
|
<!-- Card Header - Dropdown -->
|
||||||
|
<!-- <div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||||
|
<h6 class="m-0 font-weight-bold text-primary">Revenue Sources</h6>
|
||||||
|
<div class="dropdown no-arrow">
|
||||||
|
<a class="dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
<i class="fas fa-ellipsis-v fa-sm fa-fw text-gray-400"></i>
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-menu dropdown-menu-right shadow animated--fade-in" aria-labelledby="dropdownMenuLink">
|
||||||
|
<div class="dropdown-header">Dropdown Header:</div>
|
||||||
|
<a class="dropdown-item" href="#">Action</a>
|
||||||
|
<a class="dropdown-item" href="#">Another action</a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<a class="dropdown-item" href="#">Something else here</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
<!-- Card Body -->
|
||||||
|
<!-- <div class="card-body">
|
||||||
|
<div class="chart-pie pt-4 pb-2">
|
||||||
|
<canvas id="myPieChart"></canvas>
|
||||||
|
</div>
|
||||||
|
<div class="mt-4 text-center small">
|
||||||
|
<span class="mr-2">
|
||||||
|
<i class="fas fa-circle text-primary"></i> Personalia
|
||||||
|
</span>
|
||||||
|
<span class="mr-2">
|
||||||
|
<i class="fas fa-circle text-success"></i> Keuangan
|
||||||
|
</span>
|
||||||
|
<span class="mr-2">
|
||||||
|
<i class="fas fa-circle text-info"></i> Produksi
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Content Row -->
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<!-- Content Column -->
|
||||||
|
<div class="col-lg-6 mb-4">
|
||||||
|
|
||||||
|
<!-- Project Card Example -->
|
||||||
|
<!-- <div class="card shadow mb-4">
|
||||||
|
<div class="card-header py-3">
|
||||||
|
<h6 class="m-0 font-weight-bold text-primary">Projects</h6>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<h4 class="small font-weight-bold">Server Migration <span class="float-right">20%</span></h4>
|
||||||
|
<div class="progress mb-4">
|
||||||
|
<div class="progress-bar bg-danger" role="progressbar" style="width: 20%" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100"></div>
|
||||||
|
</div>
|
||||||
|
<h4 class="small font-weight-bold">Sales Tracking <span class="float-right">40%</span></h4>
|
||||||
|
<div class="progress mb-4">
|
||||||
|
<div class="progress-bar bg-warning" role="progressbar" style="width: 40%" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100"></div>
|
||||||
|
</div>
|
||||||
|
<h4 class="small font-weight-bold">Customer Database <span class="float-right">60%</span></h4>
|
||||||
|
<div class="progress mb-4">
|
||||||
|
<div class="progress-bar" role="progressbar" style="width: 60%" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100"></div>
|
||||||
|
</div>
|
||||||
|
<h4 class="small font-weight-bold">Payout Details <span class="float-right">80%</span></h4>
|
||||||
|
<div class="progress mb-4">
|
||||||
|
<div class="progress-bar bg-info" role="progressbar" style="width: 80%" aria-valuenow="80" aria-valuemin="0" aria-valuemax="100"></div>
|
||||||
|
</div>
|
||||||
|
<h4 class="small font-weight-bold">Account Setup <span class="float-right">Complete!</span></h4>
|
||||||
|
<div class="progress">
|
||||||
|
<div class="progress-bar bg-success" role="progressbar" style="width: 100%" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-6 mb-4">
|
||||||
|
|
||||||
|
<!-- Illustrations -->
|
||||||
|
<!-- <div class="card shadow mb-4">
|
||||||
|
<div class="card-header py-3">
|
||||||
|
<h6 class="m-0 font-weight-bold text-primary">Illustrations</h6>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="text-center">
|
||||||
|
<img class="img-fluid px-3 px-sm-4 mt-3 mb-4" style="width: 25rem;" src="img/undraw_posting_photo.svg" alt="">
|
||||||
|
</div>
|
||||||
|
<p>Add some quality, svg illustrations to your project courtesy of <a target="_blank" rel="nofollow" href="https://undraw.co/">unDraw</a>, a constantly updated collection of beautiful svg images that you can use completely free and without attribution!</p>
|
||||||
|
<a target="_blank" rel="nofollow" href="https://undraw.co/">Browse Illustrations on unDraw →</a>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
<!-- Approach -->
|
||||||
|
<!-- <div class="card shadow mb-4">
|
||||||
|
<div class="card-header py-3">
|
||||||
|
<h6 class="m-0 font-weight-bold text-primary">Development Approach</h6>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<p>SB Admin 2 makes extensive use of Bootstrap 4 utility classes in order to reduce CSS bloat and poor page performance. Custom CSS classes are used to create custom components and custom utility classes.</p>
|
||||||
|
<p class="mb-0">Before working with this theme, you should become familiar with the Bootstrap framework, especially the utility classes.</p>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- /.container-fluid -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Main Content -->
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<footer class="sticky-footer bg-white">
|
||||||
|
<div class="container my-auto">
|
||||||
|
<div class="copyright text-center my-auto">
|
||||||
|
<span>Copyright © Arief Hidayatullah</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
<!-- End of Footer -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Content Wrapper -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End of Page Wrapper -->
|
||||||
|
|
||||||
|
<!-- Scroll to Top Button-->
|
||||||
|
<a class="scroll-to-top rounded" href="#page-top">
|
||||||
|
<i class="fas fa-angle-up"></i>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- Logout Modal-->
|
||||||
|
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="exampleModalLabel">Ready to Leave?</h5>
|
||||||
|
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">Select "Logout" below if you are ready to end your current session.</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||||
|
<a class="btn btn-primary" href="http://localhost/rfidcam/">Logout</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Bootstrap core JavaScript-->
|
||||||
|
<script src="../src/vendor/jquery/jquery.min.js"></script>
|
||||||
|
<script src="../src/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Core plugin JavaScript-->
|
||||||
|
<script src="../src/vendor/jquery-easing/jquery.easing.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Custom scripts for all pages-->
|
||||||
|
<script src="../src/js/sb-admin-2.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Page level plugins -->
|
||||||
|
<script src="../src/vendor/chart.js/Chart.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Page level custom scripts -->
|
||||||
|
<script src="../src/js/demo/chart-area-demo.js"></script>
|
||||||
|
<script src="../src/js/demo/chart-pie-demo.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
<?php
|
||||||
|
?>
|
||||||
|
<ul class="navbar-nav bg-gradient-primary sidebar sidebar-dark accordion" id="accordionSidebar">
|
||||||
|
|
||||||
|
<!-- Sidebar - Brand -->
|
||||||
|
<a class="sidebar-brand d-flex align-items-center justify-content-center" href="index.php">
|
||||||
|
<div class="sidebar-brand-icon rotate-n-15">
|
||||||
|
<i class="fas fa-laugh-wink"></i>
|
||||||
|
</div>
|
||||||
|
<div class="sidebar-brand-text mx-3">R COLLECTION <sup></sup></div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- Divider -->
|
||||||
|
<hr class="sidebar-divider my-0">
|
||||||
|
|
||||||
|
<!-- Nav Item - Dashboard -->
|
||||||
|
<li class="nav-item active">
|
||||||
|
<a class="nav-link" href="index.php">
|
||||||
|
<i class="fas fa-fw fa-tachometer-alt"></i>
|
||||||
|
<span>Dashboard</span></a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Divider -->
|
||||||
|
<hr class="sidebar-divider">
|
||||||
|
|
||||||
|
<!-- Heading -->
|
||||||
|
<div class="sidebar-heading">
|
||||||
|
Data Absensi
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Nav Item - Charts -->
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="data_karyawan-index.php">
|
||||||
|
<i class="fas fa-fw fa-user"></i>
|
||||||
|
<span>Karyawan</span></a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Nav Item - Charts -->
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="data_absen-index.php">
|
||||||
|
<i class="fas fa-fw fa-table"></i>
|
||||||
|
<span>Absensi</span></a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Nav Item - Charts -->
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="data_invalid-index.php">
|
||||||
|
<i class="fas fa-fw fa-exclamation-triangle"></i>
|
||||||
|
<span>Invalid</span></a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Nav Item - Charts -->
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="data_registrasi.php">
|
||||||
|
<!-- <i class="fas fa-fw fa-exclamation-triangle"></i> -->
|
||||||
|
<i class="fas fa-fw fa-solid fa-user-plus"></i>
|
||||||
|
<span>Registrasi</span></a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Divider -->
|
||||||
|
<hr class="sidebar-divider">
|
||||||
|
|
||||||
|
<!-- Heading -->
|
||||||
|
<div class="sidebar-heading">
|
||||||
|
Laporan
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Nav Item - Pages Collapse Menu -->
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link collapsed" href="" data-toggle="collapse" data-target="#collapsePages" aria-expanded="true" aria-controls="collapsePages">
|
||||||
|
<i class="fas fa-fw fa-folder"></i>
|
||||||
|
<span>Rekap Absensi</span>
|
||||||
|
</a>
|
||||||
|
<div id="collapsePages" class="collapse" aria-labelledby="headingPages" data-parent="#accordionSidebar">
|
||||||
|
<div class="bg-white py-2 collapse-inner rounded">
|
||||||
|
<a class="collapse-item" href="excel.php">Ambil data</a>
|
||||||
|
<!-- <a class="collapse-item" href="#">Bulanan</a>
|
||||||
|
<a class="collapse-item" href="#">Tahunan</a> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Nav Item - Charts -->
|
||||||
|
<!-- <li class="nav-item">
|
||||||
|
<a class="nav-link" href="#">
|
||||||
|
<i class="fas fa-fw fa-chart-area"></i>
|
||||||
|
<span>Charts</span></a>
|
||||||
|
</li> -->
|
||||||
|
|
||||||
|
<!-- Divider -->
|
||||||
|
<hr class="sidebar-divider d-none d-md-block">
|
||||||
|
|
||||||
|
<!-- Sidebar Toggler (Sidebar) -->
|
||||||
|
<div class="text-center d-none d-md-inline">
|
||||||
|
<button class="rounded-circle border-0" id="sidebarToggle"></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<nav class="navbar navbar-expand navbar-light bg-white topbar mb-4 static-top shadow">
|
||||||
|
|
||||||
|
<!-- Sidebar Toggle (Topbar) -->
|
||||||
|
<button id="sidebarToggleTop" class="btn btn-link d-md-none rounded-circle mr-3">
|
||||||
|
<i class="fa fa-bars"></i>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Topbar Search -->
|
||||||
|
<form class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" class="form-control bg-light border-0 small" placeholder="Search for..." aria-label="Search" aria-describedby="basic-addon2">
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button class="btn btn-primary" type="button">
|
||||||
|
<i class="fas fa-search fa-sm"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<!-- Topbar Navbar -->
|
||||||
|
<ul class="navbar-nav ml-auto">
|
||||||
|
|
||||||
|
<!-- Nav Item - Search Dropdown (Visible Only XS) -->
|
||||||
|
<li class="nav-item dropdown no-arrow d-sm-none">
|
||||||
|
<a class="nav-link dropdown-toggle" href="#" id="searchDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
<i class="fas fa-search fa-fw"></i>
|
||||||
|
</a>
|
||||||
|
<!-- Dropdown - Messages -->
|
||||||
|
<div class="dropdown-menu dropdown-menu-right p-3 shadow animated--grow-in" aria-labelledby="searchDropdown">
|
||||||
|
<form class="form-inline mr-auto w-100 navbar-search">
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" class="form-control bg-light border-0 small" placeholder="Search for..." aria-label="Search" aria-describedby="basic-addon2">
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button class="btn btn-primary" type="button">
|
||||||
|
<i class="fas fa-search fa-sm"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<div class="topbar-divider d-none d-sm-block"></div>
|
||||||
|
|
||||||
|
<!-- Nav Item - User Information -->
|
||||||
|
<li class="nav-item dropdown no-arrow">
|
||||||
|
<a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
<span class="mr-2 d-none d-lg-inline text-gray-600 small">Admin</span>
|
||||||
|
<img class="img-profile rounded-circle" src="../src/img/arif.jpg">
|
||||||
|
</a>
|
||||||
|
<!-- Dropdown - User Information -->
|
||||||
|
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
||||||
|
<a class="dropdown-item" href="#">
|
||||||
|
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||||
|
Profile
|
||||||
|
</a>
|
||||||
|
<a class="dropdown-item" href="#">
|
||||||
|
<i class="fas fa-cogs fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||||
|
Settings
|
||||||
|
</a>
|
||||||
|
<a class="dropdown-item" href="#">
|
||||||
|
<i class="fas fa-list fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||||
|
Activity Log
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<a class="dropdown-item" href="http://localhost/rfidcam/" data-toggle="modal" data-target="#logoutModal">
|
||||||
|
<i class="fas fa-sign-out-alt fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||||
|
Logout
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</nav>
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
<?php
|
||||||
|
// Sertakan file konfigurasi
|
||||||
|
require_once "config.php";
|
||||||
|
|
||||||
|
// Tentukan variabel dan inisialisasi dengan nilai kosong
|
||||||
|
$idrfid = $nama = $password = "";
|
||||||
|
$idrfid_err = $nama_err = $password_err = "";
|
||||||
|
|
||||||
|
if($_SERVER["REQUEST_METHOD"] == "POST"){
|
||||||
|
|
||||||
|
// Validasi IDRFID
|
||||||
|
if(empty(trim($_POST["idrfid"]))){
|
||||||
|
$idrfid_err = "Masukkan IDRFID.";
|
||||||
|
} else {
|
||||||
|
// Siapkan pernyataan select
|
||||||
|
$sql = "SELECT id FROM data_registrasi WHERE idrfid = ?";
|
||||||
|
|
||||||
|
if($stmt = mysqli_prepare($link, $sql)){
|
||||||
|
// Ikat variabel ke pernyataan yang disiapkan sebagai parameter
|
||||||
|
mysqli_stmt_bind_param($stmt, "s", $param_idrfid);
|
||||||
|
|
||||||
|
// Tetapkan parameter
|
||||||
|
$param_idrfid = trim($_POST["idrfid"]);
|
||||||
|
|
||||||
|
// Coba jalankan pernyataan yang disiapkan
|
||||||
|
if(mysqli_stmt_execute($stmt)){
|
||||||
|
/* simpan hasil */
|
||||||
|
mysqli_stmt_store_result($stmt);
|
||||||
|
|
||||||
|
if(mysqli_stmt_num_rows($stmt) == 1){
|
||||||
|
$idrfid_err = "IDRFID ini sudah digunakan.";
|
||||||
|
} else {
|
||||||
|
$idrfid = trim($_POST["idrfid"]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo "Ups! Terjadi kesalahan. Silakan coba lagi nanti.";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tutup pernyataan
|
||||||
|
mysqli_stmt_close($stmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validasi nama
|
||||||
|
if(empty(trim($_POST["nama"]))){
|
||||||
|
$nama_err = "Masukkan nama.";
|
||||||
|
} else {
|
||||||
|
$nama = trim($_POST["nama"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validasi kata sandi
|
||||||
|
if(empty(trim($_POST["password"]))){
|
||||||
|
$password_err = "Masukkan kata sandi.";
|
||||||
|
} else {
|
||||||
|
$password = trim($_POST["password"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Periksa kesalahan input sebelum memasukkan ke database
|
||||||
|
if(empty($idrfid_err) && empty($nama_err) && empty($password_err)){
|
||||||
|
// Siapkan pernyataan insert
|
||||||
|
$sql = "INSERT INTO data_registrasi (idrfid, nama, password) VALUES (?, ?, ?)";
|
||||||
|
|
||||||
|
if($stmt = mysqli_prepare($link, $sql)){
|
||||||
|
// Ikat variabel ke pernyataan yang disiapkan sebagai parameter
|
||||||
|
mysqli_stmt_bind_param($stmt, "sss", $param_idrfid, $param_nama, $param_password);
|
||||||
|
|
||||||
|
// Tetapkan parameter
|
||||||
|
$param_idrfid = $idrfid;
|
||||||
|
$param_nama = $nama;
|
||||||
|
$param_password = password_hash($password, PASSWORD_DEFAULT); // Membuat hash kata sandi
|
||||||
|
|
||||||
|
// Coba jalankan pernyataan yang disiapkan
|
||||||
|
if(mysqli_stmt_execute($stmt)){
|
||||||
|
// Arahkan ke halaman utama
|
||||||
|
header("location: index.php");
|
||||||
|
} else {
|
||||||
|
echo "Terjadi kesalahan. Silakan coba lagi nanti.";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tutup pernyataan
|
||||||
|
mysqli_stmt_close($stmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tutup koneksi
|
||||||
|
mysqli_close($link);
|
||||||
|
}
|
||||||
|
?>
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,35 @@
|
||||||
|
CREATE DATABASE IF NOT EXISTS absensi;
|
||||||
|
USE absensi;
|
||||||
|
|
||||||
|
/*Table structure for table `data_absen` */
|
||||||
|
CREATE TABLE data_absen (
|
||||||
|
id int(100) NOT NULL AUTO_INCREMENT,
|
||||||
|
tanggal date NOT NULL DEFAULT current_timestamp(),
|
||||||
|
waktu time NOT NULL DEFAULT current_timestamp(),
|
||||||
|
uid varchar(20) NOT NULL,
|
||||||
|
status varchar(20) NOT NULL,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
/*Table structure for table `data_invalid` */
|
||||||
|
CREATE TABLE data_invalid (
|
||||||
|
id int(100) NOT NULL AUTO_INCREMENT,
|
||||||
|
tanggal date NOT NULL DEFAULT current_timestamp(),
|
||||||
|
waktu time NOT NULL DEFAULT current_timestamp(),
|
||||||
|
uid varchar(10) NOT NULL,
|
||||||
|
status varchar(10) NOT NULL,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
/*Table structure for table `data_karyawan` */
|
||||||
|
CREATE TABLE data_karyawan (
|
||||||
|
id int(50) NOT NULL AUTO_INCREMENT,
|
||||||
|
created date NOT NULL DEFAULT current_timestamp(),
|
||||||
|
uid varchar(20) NOT NULL,
|
||||||
|
nama varchar(50) NOT NULL,
|
||||||
|
division varchar(50) NOT NULL,
|
||||||
|
mail varchar(50) NOT NULL,
|
||||||
|
alamat text NOT NULL,
|
||||||
|
picture varchar(100) NOT NULL,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?php
|
||||||
|
header('Location: apps'); /* Redirect browser */
|
||||||
|
|
||||||
|
/* Make sure that code below does not get executed when we redirect. */
|
||||||
|
exit;
|
||||||
|
?>
|
||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 44 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 36 KiB |
|
|
@ -0,0 +1,118 @@
|
||||||
|
// Set new default font family and font color to mimic Bootstrap's default styling
|
||||||
|
Chart.defaults.global.defaultFontFamily = 'Nunito', '-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif';
|
||||||
|
Chart.defaults.global.defaultFontColor = '#858796';
|
||||||
|
|
||||||
|
function number_format(number, decimals, dec_point, thousands_sep) {
|
||||||
|
// * example: number_format(1234.56, 2, ',', ' ');
|
||||||
|
// * return: '1 234,56'
|
||||||
|
number = (number + '').replace(',', '').replace(' ', '');
|
||||||
|
var n = !isFinite(+number) ? 0 : +number,
|
||||||
|
prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
|
||||||
|
sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
|
||||||
|
dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
|
||||||
|
s = '',
|
||||||
|
toFixedFix = function(n, prec) {
|
||||||
|
var k = Math.pow(10, prec);
|
||||||
|
return '' + Math.round(n * k) / k;
|
||||||
|
};
|
||||||
|
// Fix for IE parseFloat(0.55).toFixed(0) = 0;
|
||||||
|
s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
|
||||||
|
if (s[0].length > 3) {
|
||||||
|
s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
|
||||||
|
}
|
||||||
|
if ((s[1] || '').length < prec) {
|
||||||
|
s[1] = s[1] || '';
|
||||||
|
s[1] += new Array(prec - s[1].length + 1).join('0');
|
||||||
|
}
|
||||||
|
return s.join(dec);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Area Chart Example
|
||||||
|
var ctx = document.getElementById("myAreaChart");
|
||||||
|
var myLineChart = new Chart(ctx, {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
|
||||||
|
datasets: [{
|
||||||
|
label: "Earnings",
|
||||||
|
lineTension: 0.3,
|
||||||
|
backgroundColor: "rgba(78, 115, 223, 0.05)",
|
||||||
|
borderColor: "rgba(78, 115, 223, 1)",
|
||||||
|
pointRadius: 3,
|
||||||
|
pointBackgroundColor: "rgba(78, 115, 223, 1)",
|
||||||
|
pointBorderColor: "rgba(78, 115, 223, 1)",
|
||||||
|
pointHoverRadius: 3,
|
||||||
|
pointHoverBackgroundColor: "rgba(78, 115, 223, 1)",
|
||||||
|
pointHoverBorderColor: "rgba(78, 115, 223, 1)",
|
||||||
|
pointHitRadius: 10,
|
||||||
|
pointBorderWidth: 2,
|
||||||
|
data: [0, 10000, 5000, 15000, 10000, 20000, 15000, 25000, 20000, 30000, 25000, 40000],
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
layout: {
|
||||||
|
padding: {
|
||||||
|
left: 10,
|
||||||
|
right: 25,
|
||||||
|
top: 25,
|
||||||
|
bottom: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
xAxes: [{
|
||||||
|
time: {
|
||||||
|
unit: 'date'
|
||||||
|
},
|
||||||
|
gridLines: {
|
||||||
|
display: false,
|
||||||
|
drawBorder: false
|
||||||
|
},
|
||||||
|
ticks: {
|
||||||
|
maxTicksLimit: 7
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
yAxes: [{
|
||||||
|
ticks: {
|
||||||
|
maxTicksLimit: 5,
|
||||||
|
padding: 10,
|
||||||
|
// Include a dollar sign in the ticks
|
||||||
|
callback: function(value, index, values) {
|
||||||
|
return '$' + number_format(value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
gridLines: {
|
||||||
|
color: "rgb(234, 236, 244)",
|
||||||
|
zeroLineColor: "rgb(234, 236, 244)",
|
||||||
|
drawBorder: false,
|
||||||
|
borderDash: [2],
|
||||||
|
zeroLineBorderDash: [2]
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
display: false
|
||||||
|
},
|
||||||
|
tooltips: {
|
||||||
|
backgroundColor: "rgb(255,255,255)",
|
||||||
|
bodyFontColor: "#858796",
|
||||||
|
titleMarginBottom: 10,
|
||||||
|
titleFontColor: '#6e707e',
|
||||||
|
titleFontSize: 14,
|
||||||
|
borderColor: '#dddfeb',
|
||||||
|
borderWidth: 1,
|
||||||
|
xPadding: 15,
|
||||||
|
yPadding: 15,
|
||||||
|
displayColors: false,
|
||||||
|
intersect: false,
|
||||||
|
mode: 'index',
|
||||||
|
caretPadding: 10,
|
||||||
|
callbacks: {
|
||||||
|
label: function(tooltipItem, chart) {
|
||||||
|
var datasetLabel = chart.datasets[tooltipItem.datasetIndex].label || '';
|
||||||
|
return datasetLabel + ': $' + number_format(tooltipItem.yLabel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,111 @@
|
||||||
|
// Set new default font family and font color to mimic Bootstrap's default styling
|
||||||
|
Chart.defaults.global.defaultFontFamily = 'Nunito', '-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif';
|
||||||
|
Chart.defaults.global.defaultFontColor = '#858796';
|
||||||
|
|
||||||
|
function number_format(number, decimals, dec_point, thousands_sep) {
|
||||||
|
// * example: number_format(1234.56, 2, ',', ' ');
|
||||||
|
// * return: '1 234,56'
|
||||||
|
number = (number + '').replace(',', '').replace(' ', '');
|
||||||
|
var n = !isFinite(+number) ? 0 : +number,
|
||||||
|
prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
|
||||||
|
sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
|
||||||
|
dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
|
||||||
|
s = '',
|
||||||
|
toFixedFix = function(n, prec) {
|
||||||
|
var k = Math.pow(10, prec);
|
||||||
|
return '' + Math.round(n * k) / k;
|
||||||
|
};
|
||||||
|
// Fix for IE parseFloat(0.55).toFixed(0) = 0;
|
||||||
|
s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
|
||||||
|
if (s[0].length > 3) {
|
||||||
|
s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
|
||||||
|
}
|
||||||
|
if ((s[1] || '').length < prec) {
|
||||||
|
s[1] = s[1] || '';
|
||||||
|
s[1] += new Array(prec - s[1].length + 1).join('0');
|
||||||
|
}
|
||||||
|
return s.join(dec);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bar Chart Example
|
||||||
|
var ctx = document.getElementById("myBarChart");
|
||||||
|
var myBarChart = new Chart(ctx, {
|
||||||
|
type: 'bar',
|
||||||
|
data: {
|
||||||
|
labels: ["January", "February", "March", "April", "May", "June"],
|
||||||
|
datasets: [{
|
||||||
|
label: "Revenue",
|
||||||
|
backgroundColor: "#4e73df",
|
||||||
|
hoverBackgroundColor: "#2e59d9",
|
||||||
|
borderColor: "#4e73df",
|
||||||
|
data: [4215, 5312, 6251, 7841, 9821, 14984],
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
layout: {
|
||||||
|
padding: {
|
||||||
|
left: 10,
|
||||||
|
right: 25,
|
||||||
|
top: 25,
|
||||||
|
bottom: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
xAxes: [{
|
||||||
|
time: {
|
||||||
|
unit: 'month'
|
||||||
|
},
|
||||||
|
gridLines: {
|
||||||
|
display: false,
|
||||||
|
drawBorder: false
|
||||||
|
},
|
||||||
|
ticks: {
|
||||||
|
maxTicksLimit: 6
|
||||||
|
},
|
||||||
|
maxBarThickness: 25,
|
||||||
|
}],
|
||||||
|
yAxes: [{
|
||||||
|
ticks: {
|
||||||
|
min: 0,
|
||||||
|
max: 15000,
|
||||||
|
maxTicksLimit: 5,
|
||||||
|
padding: 10,
|
||||||
|
// Include a dollar sign in the ticks
|
||||||
|
callback: function(value, index, values) {
|
||||||
|
return '$' + number_format(value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
gridLines: {
|
||||||
|
color: "rgb(234, 236, 244)",
|
||||||
|
zeroLineColor: "rgb(234, 236, 244)",
|
||||||
|
drawBorder: false,
|
||||||
|
borderDash: [2],
|
||||||
|
zeroLineBorderDash: [2]
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
display: false
|
||||||
|
},
|
||||||
|
tooltips: {
|
||||||
|
titleMarginBottom: 10,
|
||||||
|
titleFontColor: '#6e707e',
|
||||||
|
titleFontSize: 14,
|
||||||
|
backgroundColor: "rgb(255,255,255)",
|
||||||
|
bodyFontColor: "#858796",
|
||||||
|
borderColor: '#dddfeb',
|
||||||
|
borderWidth: 1,
|
||||||
|
xPadding: 15,
|
||||||
|
yPadding: 15,
|
||||||
|
displayColors: false,
|
||||||
|
caretPadding: 10,
|
||||||
|
callbacks: {
|
||||||
|
label: function(tooltipItem, chart) {
|
||||||
|
var datasetLabel = chart.datasets[tooltipItem.datasetIndex].label || '';
|
||||||
|
return datasetLabel + ': $' + number_format(tooltipItem.yLabel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
// Set new default font family and font color to mimic Bootstrap's default styling
|
||||||
|
Chart.defaults.global.defaultFontFamily = 'Nunito', '-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif';
|
||||||
|
Chart.defaults.global.defaultFontColor = '#858796';
|
||||||
|
|
||||||
|
// Pie Chart Example
|
||||||
|
var ctx = document.getElementById("myPieChart");
|
||||||
|
var myPieChart = new Chart(ctx, {
|
||||||
|
type: 'doughnut',
|
||||||
|
data: {
|
||||||
|
labels: ["Personalia", "Keuangan", "Produksi"],
|
||||||
|
datasets: [{
|
||||||
|
data: [55, 30, 15],
|
||||||
|
backgroundColor: ['#4e73df', '#1cc88a', '#36b9cc'],
|
||||||
|
hoverBackgroundColor: ['#2e59d9', '#17a673', '#2c9faf'],
|
||||||
|
hoverBorderColor: "rgba(234, 236, 244, 1)",
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
tooltips: {
|
||||||
|
backgroundColor: "rgb(255,255,255)",
|
||||||
|
bodyFontColor: "#858796",
|
||||||
|
borderColor: '#dddfeb',
|
||||||
|
borderWidth: 1,
|
||||||
|
xPadding: 15,
|
||||||
|
yPadding: 15,
|
||||||
|
displayColors: false,
|
||||||
|
caretPadding: 10,
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
display: false
|
||||||
|
},
|
||||||
|
cutoutPercentage: 80,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
// Call the dataTables jQuery plugin
|
||||||
|
$(document).ready(function() {
|
||||||
|
$('#dataTable').DataTable();
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
(function($) {
|
||||||
|
"use strict"; // Start of use strict
|
||||||
|
|
||||||
|
// Toggle the side navigation
|
||||||
|
$("#sidebarToggle, #sidebarToggleTop").on('click', function(e) {
|
||||||
|
$("body").toggleClass("sidebar-toggled");
|
||||||
|
$(".sidebar").toggleClass("toggled");
|
||||||
|
if ($(".sidebar").hasClass("toggled")) {
|
||||||
|
$('.sidebar .collapse').collapse('hide');
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Close any open menu accordions when window is resized below 768px
|
||||||
|
$(window).resize(function() {
|
||||||
|
if ($(window).width() < 768) {
|
||||||
|
$('.sidebar .collapse').collapse('hide');
|
||||||
|
};
|
||||||
|
|
||||||
|
// Toggle the side navigation when window is resized below 480px
|
||||||
|
if ($(window).width() < 480 && !$(".sidebar").hasClass("toggled")) {
|
||||||
|
$("body").addClass("sidebar-toggled");
|
||||||
|
$(".sidebar").addClass("toggled");
|
||||||
|
$('.sidebar .collapse').collapse('hide');
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Prevent the content wrapper from scrolling when the fixed side navigation hovered over
|
||||||
|
$('body.fixed-nav .sidebar').on('mousewheel DOMMouseScroll wheel', function(e) {
|
||||||
|
if ($(window).width() > 768) {
|
||||||
|
var e0 = e.originalEvent,
|
||||||
|
delta = e0.wheelDelta || -e0.detail;
|
||||||
|
this.scrollTop += (delta < 0 ? 1 : -1) * 30;
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Scroll to top button appear
|
||||||
|
$(document).on('scroll', function() {
|
||||||
|
var scrollDistance = $(this).scrollTop();
|
||||||
|
if (scrollDistance > 100) {
|
||||||
|
$('.scroll-to-top').fadeIn();
|
||||||
|
} else {
|
||||||
|
$('.scroll-to-top').fadeOut();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Smooth scrolling using jQuery easing
|
||||||
|
$(document).on('click', 'a.scroll-to-top', function(e) {
|
||||||
|
var $anchor = $(this);
|
||||||
|
$('html, body').stop().animate({
|
||||||
|
scrollTop: ($($anchor.attr('href')).offset().top)
|
||||||
|
}, 1000, 'easeInOutExpo');
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
})(jQuery); // End of use strict
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
/*!
|
||||||
|
* Start Bootstrap - SB Admin 2 v4.1.1 (https://startbootstrap.com/themes/sb-admin-2)
|
||||||
|
* Copyright 2013-2020 Start Bootstrap
|
||||||
|
* Licensed under MIT (https://github.com/StartBootstrap/startbootstrap-sb-admin-2/blob/master/LICENSE)
|
||||||
|
*/
|
||||||
|
|
||||||
|
!function(s){"use strict";s("#sidebarToggle, #sidebarToggleTop").on("click",function(e){s("body").toggleClass("sidebar-toggled"),s(".sidebar").toggleClass("toggled"),s(".sidebar").hasClass("toggled")&&s(".sidebar .collapse").collapse("hide")}),s(window).resize(function(){s(window).width()<768&&s(".sidebar .collapse").collapse("hide"),s(window).width()<480&&!s(".sidebar").hasClass("toggled")&&(s("body").addClass("sidebar-toggled"),s(".sidebar").addClass("toggled"),s(".sidebar .collapse").collapse("hide"))}),s("body.fixed-nav .sidebar").on("mousewheel DOMMouseScroll wheel",function(e){if(768<s(window).width()){var o=e.originalEvent,l=o.wheelDelta||-o.detail;this.scrollTop+=30*(l<0?1:-1),e.preventDefault()}}),s(document).on("scroll",function(){100<s(this).scrollTop()?s(".scroll-to-top").fadeIn():s(".scroll-to-top").fadeOut()}),s(document).on("click","a.scroll-to-top",function(e){var o=s(this);s("html, body").stop().animate({scrollTop:s(o.attr("href")).offset().top},1e3,"easeInOutExpo"),e.preventDefault()})}(jQuery);
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
.btn-circle {
|
||||||
|
border-radius: 100%;
|
||||||
|
height: 2.5rem;
|
||||||
|
width: 2.5rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
&.btn-sm {
|
||||||
|
height: 1.8rem;
|
||||||
|
width: 1.8rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
||||||
|
&.btn-lg {
|
||||||
|
height: 3.5rem;
|
||||||
|
width: 3.5rem;
|
||||||
|
font-size: 1.35rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-icon-split {
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: center;
|
||||||
|
.icon {
|
||||||
|
background: fade-out($black, .85);
|
||||||
|
display: inline-block;
|
||||||
|
padding: $btn-padding-y $btn-padding-x;
|
||||||
|
}
|
||||||
|
.text {
|
||||||
|
display: inline-block;
|
||||||
|
padding: $btn-padding-y $btn-padding-x;
|
||||||
|
}
|
||||||
|
&.btn-sm {
|
||||||
|
.icon {
|
||||||
|
padding: $btn-padding-y-sm $btn-padding-x-sm;
|
||||||
|
}
|
||||||
|
.text {
|
||||||
|
padding: $btn-padding-y-sm $btn-padding-x-sm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.btn-lg {
|
||||||
|
.icon {
|
||||||
|
padding: $btn-padding-y-lg $btn-padding-x-lg;
|
||||||
|
}
|
||||||
|
.text {
|
||||||
|
padding: $btn-padding-y-lg $btn-padding-x-lg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
// Custom Card Styling
|
||||||
|
|
||||||
|
.card {
|
||||||
|
.card-header {
|
||||||
|
// Format Dropdowns in Card Headings
|
||||||
|
.dropdown {
|
||||||
|
line-height: 1;
|
||||||
|
.dropdown-menu {
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Collapsable Card Styling
|
||||||
|
.card-header[data-toggle="collapse"] {
|
||||||
|
text-decoration: none;
|
||||||
|
position: relative;
|
||||||
|
padding: 0.75rem 3.25rem 0.75rem 1.25rem;
|
||||||
|
&::after {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
padding-right: 1.725rem;
|
||||||
|
line-height: 51px;
|
||||||
|
font-weight: 900;
|
||||||
|
content: '\f107';
|
||||||
|
font-family: 'Font Awesome 5 Free';
|
||||||
|
color: $gray-400;
|
||||||
|
}
|
||||||
|
&.collapsed {
|
||||||
|
border-radius: $card-border-radius;
|
||||||
|
&::after {
|
||||||
|
content: '\f105';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
// Area Chart
|
||||||
|
.chart-area {
|
||||||
|
position: relative;
|
||||||
|
height: 10rem;
|
||||||
|
width: 100%;
|
||||||
|
@include media-breakpoint-up(md) {
|
||||||
|
height: 20rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bar Chart
|
||||||
|
.chart-bar {
|
||||||
|
position: relative;
|
||||||
|
height: 10rem;
|
||||||
|
width: 100%;
|
||||||
|
@include media-breakpoint-up(md) {
|
||||||
|
height: 20rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pie Chart
|
||||||
|
.chart-pie {
|
||||||
|
position: relative;
|
||||||
|
height: 15rem;
|
||||||
|
width: 100%;
|
||||||
|
@include media-breakpoint-up(md) {
|
||||||
|
height: calc(20rem - 43px) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
// Custom Dropdown Styling
|
||||||
|
|
||||||
|
.dropdown {
|
||||||
|
.dropdown-menu {
|
||||||
|
font-size: $dropdown-font-size;
|
||||||
|
.dropdown-header {
|
||||||
|
@extend .text-uppercase;
|
||||||
|
font-weight: 800;
|
||||||
|
font-size: 0.65rem;
|
||||||
|
color: $gray-500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utility class to hide arrow from dropdown
|
||||||
|
|
||||||
|
.dropdown.no-arrow {
|
||||||
|
.dropdown-toggle::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
// Lucas Bebber's Glitch Effect
|
||||||
|
// Tutorial and CSS from CSS Tricks
|
||||||
|
// https://css-tricks.com/glitch-effect-text-images-svg/
|
||||||
|
|
||||||
|
.error {
|
||||||
|
color: $gray-800;
|
||||||
|
font-size: 7rem;
|
||||||
|
position: relative;
|
||||||
|
line-height: 1;
|
||||||
|
width: 12.5rem;
|
||||||
|
}
|
||||||
|
@keyframes noise-anim {
|
||||||
|
$steps: 20;
|
||||||
|
@for $i from 0 through $steps {
|
||||||
|
#{percentage($i*(1/$steps))} {
|
||||||
|
clip: rect(random(100)+px,9999px,random(100)+px,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.error:after {
|
||||||
|
content: attr(data-text);
|
||||||
|
position: absolute;
|
||||||
|
left: 2px;
|
||||||
|
text-shadow: -1px 0 $red;
|
||||||
|
top: 0;
|
||||||
|
color: $gray-800;
|
||||||
|
background: $gray-100;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0,900px,0,0);
|
||||||
|
animation: noise-anim 2s infinite linear alternate-reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes noise-anim-2 {
|
||||||
|
$steps: 20;
|
||||||
|
@for $i from 0 through $steps {
|
||||||
|
#{percentage($i*(1/$steps))} {
|
||||||
|
clip: rect(random(100)+px,9999px,random(100)+px,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.error:before {
|
||||||
|
content: attr(data-text);
|
||||||
|
position: absolute;
|
||||||
|
left: -2px;
|
||||||
|
text-shadow: 1px 0 $blue;
|
||||||
|
top: 0;
|
||||||
|
color: $gray-800;
|
||||||
|
background: $gray-100;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0,900px,0,0);
|
||||||
|
animation: noise-anim-2 3s infinite linear alternate-reverse;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
footer.sticky-footer {
|
||||||
|
padding: 2rem 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
.copyright {
|
||||||
|
line-height: 1;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body.sidebar-toggled {
|
||||||
|
footer.sticky-footer {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
// Global component styles
|
||||||
|
|
||||||
|
html {
|
||||||
|
position: relative;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main page wrapper
|
||||||
|
#wrapper {
|
||||||
|
display: flex;
|
||||||
|
#content-wrapper {
|
||||||
|
background-color: $gray-100;
|
||||||
|
width: 100%;
|
||||||
|
overflow-x: hidden;
|
||||||
|
#content {
|
||||||
|
flex: 1 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set container padding to match gutter width instead of default 15px
|
||||||
|
.container,
|
||||||
|
.container-fluid {
|
||||||
|
padding-left: $grid-gutter-width;
|
||||||
|
padding-right: $grid-gutter-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scroll to top button
|
||||||
|
.scroll-to-top {
|
||||||
|
position: fixed;
|
||||||
|
right: 1rem;
|
||||||
|
bottom: 1rem;
|
||||||
|
display: none;
|
||||||
|
width: 2.75rem;
|
||||||
|
height: 2.75rem;
|
||||||
|
text-align: center;
|
||||||
|
color: $white;
|
||||||
|
background: fade-out($gray-800, .5);
|
||||||
|
line-height: 46px;
|
||||||
|
&:focus,
|
||||||
|
&:hover {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
background: $gray-800;
|
||||||
|
}
|
||||||
|
i {
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
// Pulling these images from Unsplash
|
||||||
|
// Toshi the dog from https://unsplash.com/@charlesdeluvio - what a funny dog...
|
||||||
|
|
||||||
|
.bg-login-image {
|
||||||
|
background: url($login-image);
|
||||||
|
background-position: center;
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-register-image {
|
||||||
|
background: url($register-image);
|
||||||
|
background-position: center;
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-password-image {
|
||||||
|
background: url($password-image);
|
||||||
|
background-position: center;
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
form.user {
|
||||||
|
|
||||||
|
.custom-checkbox.small {
|
||||||
|
label {
|
||||||
|
line-height: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control-user {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
border-radius: 10rem;
|
||||||
|
padding: 1.5rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-user {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
border-radius: 10rem;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-google {
|
||||||
|
@include button-variant($brand-google, $white);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-facebook {
|
||||||
|
@include button-variant($brand-facebook, $white);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
@import "navs/global.scss";
|
||||||
|
@import "navs/topbar.scss";
|
||||||
|
@import "navs/sidebar.scss";
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
@import "utilities/animation.scss";
|
||||||
|
@import "utilities/background.scss";
|
||||||
|
@import "utilities/display.scss";
|
||||||
|
@import "utilities/text.scss";
|
||||||
|
@import "utilities/border.scss";
|
||||||
|
@import "utilities/progress.scss";
|
||||||
|
@import "utilities/rotate.scss";
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
// Override Bootstrap default variables here
|
||||||
|
// Do not edit any of the files in /vendor/bootstrap/scss/!
|
||||||
|
|
||||||
|
// Color Variables
|
||||||
|
// Bootstrap Color Overrides
|
||||||
|
|
||||||
|
$white: #fff !default;
|
||||||
|
$gray-100: #f8f9fc !default;
|
||||||
|
$gray-200: #eaecf4 !default;
|
||||||
|
$gray-300: #dddfeb !default;
|
||||||
|
$gray-400: #d1d3e2 !default;
|
||||||
|
$gray-500: #b7b9cc !default;
|
||||||
|
$gray-600: #858796 !default;
|
||||||
|
$gray-700: #6e707e !default;
|
||||||
|
$gray-800: #5a5c69 !default;
|
||||||
|
$gray-900: #3a3b45 !default;
|
||||||
|
$black: #000 !default;
|
||||||
|
|
||||||
|
$blue: #4e73df !default;
|
||||||
|
$indigo: #6610f2 !default;
|
||||||
|
$purple: #6f42c1 !default;
|
||||||
|
$pink: #e83e8c !default;
|
||||||
|
$red: #e74a3b !default;
|
||||||
|
$orange: #fd7e14 !default;
|
||||||
|
$yellow: #f6c23e !default;
|
||||||
|
$green: #1cc88a !default;
|
||||||
|
$teal: #20c9a6 !default;
|
||||||
|
$cyan: #36b9cc !default;
|
||||||
|
|
||||||
|
// Custom Colors
|
||||||
|
$brand-google: #ea4335 !default;
|
||||||
|
$brand-facebook: #3b5998 !default;
|
||||||
|
|
||||||
|
// Set Contrast Threshold
|
||||||
|
$yiq-contrasted-threshold: 195 !default;
|
||||||
|
|
||||||
|
// Typography
|
||||||
|
$body-color: $gray-600 !default;
|
||||||
|
|
||||||
|
$font-family-sans-serif: "Nunito", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", 'Noto Color Emoji' !default;
|
||||||
|
|
||||||
|
$font-weight-light: 300 !default;
|
||||||
|
// $font-weight-base: 400;
|
||||||
|
$headings-font-weight: 400 !default;
|
||||||
|
|
||||||
|
// Shadows
|
||||||
|
$box-shadow-sm: 0 0.125rem 0.25rem 0 rgba($gray-900, .2) !default;
|
||||||
|
$box-shadow: 0 0.15rem 1.75rem 0 rgba($gray-900, .15) !default;
|
||||||
|
// $box-shadow-lg: 0 1rem 3rem rgba($black, .175) !default;
|
||||||
|
|
||||||
|
// Borders Radius
|
||||||
|
$border-radius: 0.35rem !default;
|
||||||
|
$border-color: darken($gray-200, 2%) !default;
|
||||||
|
|
||||||
|
// Spacing Variables
|
||||||
|
// Change below variable if the height of the navbar changes
|
||||||
|
$topbar-base-height: 4.375rem !default;
|
||||||
|
// Change below variable to change the width of the sidenav
|
||||||
|
$sidebar-base-width: 14rem !default;
|
||||||
|
// Change below variable to change the width of the sidenav when collapsed
|
||||||
|
$sidebar-collapsed-width: 6.5rem !default;
|
||||||
|
|
||||||
|
// Card
|
||||||
|
$card-cap-bg: $gray-100 !default;
|
||||||
|
$card-border-color: $border-color !default;
|
||||||
|
|
||||||
|
// Adjust column spacing for symmetry
|
||||||
|
$spacer: 1rem !default;
|
||||||
|
$grid-gutter-width: $spacer * 1.5 !default;
|
||||||
|
|
||||||
|
// Transitions
|
||||||
|
$transition-collapse: height .15s ease !default;
|
||||||
|
|
||||||
|
// Dropdowns
|
||||||
|
$dropdown-font-size: 0.85rem !default;
|
||||||
|
$dropdown-border-color: $border-color !default;
|
||||||
|
|
||||||
|
// Images
|
||||||
|
$login-image: 'https://source.unsplash.com/K4mSJ7kc0As/600x800' !default;
|
||||||
|
$register-image: 'https://source.unsplash.com/Mv9hjnEUHR4/600x800' !default;
|
||||||
|
$password-image: 'https://source.unsplash.com/oWTW-jNGl9I/600x800' !default;
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
// Global styles for both custom sidebar and topbar compoments
|
||||||
|
|
||||||
|
.sidebar,
|
||||||
|
.topbar {
|
||||||
|
.nav-item {
|
||||||
|
// Customize Dropdown Arrows for Navbar
|
||||||
|
&.dropdown {
|
||||||
|
.dropdown-toggle {
|
||||||
|
&::after {
|
||||||
|
width: 1rem;
|
||||||
|
text-align: center;
|
||||||
|
float: right;
|
||||||
|
vertical-align: 0;
|
||||||
|
border: 0;
|
||||||
|
font-weight: 900;
|
||||||
|
content: '\f105';
|
||||||
|
font-family: 'Font Awesome 5 Free';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.show {
|
||||||
|
.dropdown-toggle::after {
|
||||||
|
content: '\f107';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Counter for nav links and nav link image sizing
|
||||||
|
.nav-link {
|
||||||
|
position: relative;
|
||||||
|
.badge-counter {
|
||||||
|
position: absolute;
|
||||||
|
transform: scale(0.7);
|
||||||
|
transform-origin: top right;
|
||||||
|
right: .25rem;
|
||||||
|
margin-top: -.25rem;
|
||||||
|
}
|
||||||
|
.img-profile {
|
||||||
|
height: 2rem;
|
||||||
|
width: 2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,372 @@
|
||||||
|
// Sidebar
|
||||||
|
.sidebar {
|
||||||
|
width: $sidebar-collapsed-width;
|
||||||
|
min-height: 100vh;
|
||||||
|
.nav-item {
|
||||||
|
position: relative;
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
.nav-link {
|
||||||
|
text-align: center;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
width: $sidebar-collapsed-width;
|
||||||
|
span {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.active {
|
||||||
|
.nav-link {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Accordion
|
||||||
|
.collapse {
|
||||||
|
position: absolute;
|
||||||
|
left: calc(#{$sidebar-collapsed-width} + #{$grid-gutter-width} / 2);
|
||||||
|
z-index: 1;
|
||||||
|
top: 2px;
|
||||||
|
// Grow In Animation
|
||||||
|
@extend .animated--grow-in;
|
||||||
|
.collapse-inner {
|
||||||
|
border-radius: $border-radius;
|
||||||
|
box-shadow: $box-shadow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.collapsing {
|
||||||
|
display: none;
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
.collapse,
|
||||||
|
.collapsing {
|
||||||
|
.collapse-inner {
|
||||||
|
padding: .5rem 0;
|
||||||
|
min-width: 10rem;
|
||||||
|
font-size: $dropdown-font-size;
|
||||||
|
margin: 0 0 1rem 0;
|
||||||
|
.collapse-header {
|
||||||
|
margin: 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
padding: .5rem 1.5rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: 800;
|
||||||
|
font-size: 0.65rem;
|
||||||
|
color: $gray-500;
|
||||||
|
}
|
||||||
|
.collapse-item {
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
margin: 0 0.5rem;
|
||||||
|
display: block;
|
||||||
|
color: $gray-900;
|
||||||
|
text-decoration: none;
|
||||||
|
border-radius: $border-radius;
|
||||||
|
white-space: nowrap;
|
||||||
|
&:hover {
|
||||||
|
background-color: $gray-200;
|
||||||
|
}
|
||||||
|
&:active {
|
||||||
|
background-color: $gray-300;
|
||||||
|
}
|
||||||
|
&.active {
|
||||||
|
color: $primary;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#sidebarToggle {
|
||||||
|
width: 2.5rem;
|
||||||
|
height: 2.5rem;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
cursor: pointer;
|
||||||
|
&::after {
|
||||||
|
font-weight: 900;
|
||||||
|
content: '\f104';
|
||||||
|
font-family: 'Font Awesome 5 Free';
|
||||||
|
margin-right: 0.1rem;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.toggled {
|
||||||
|
width: 0 !important;
|
||||||
|
overflow: hidden;
|
||||||
|
#sidebarToggle::after {
|
||||||
|
content: '\f105';
|
||||||
|
font-family: 'Font Awesome 5 Free';
|
||||||
|
margin-left: 0.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.sidebar-brand {
|
||||||
|
height: $topbar-base-height;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 800;
|
||||||
|
padding: 1.5rem 1rem;
|
||||||
|
text-align: center;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.05rem;
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
|
.sidebar-brand-icon i {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
.sidebar-brand-text {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hr.sidebar-divider {
|
||||||
|
margin: 0 1rem 1rem;
|
||||||
|
}
|
||||||
|
.sidebar-heading {
|
||||||
|
text-align: center;
|
||||||
|
padding: 0 1rem;
|
||||||
|
font-weight: 800;
|
||||||
|
font-size: 0.65rem;
|
||||||
|
@extend .text-uppercase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-breakpoint-up(md) {
|
||||||
|
.sidebar {
|
||||||
|
width: $sidebar-base-width !important;
|
||||||
|
.nav-item {
|
||||||
|
// Accordion
|
||||||
|
.collapse {
|
||||||
|
position: relative;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1;
|
||||||
|
top: 0;
|
||||||
|
animation: none;
|
||||||
|
.collapse-inner {
|
||||||
|
border-radius: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.collapsing {
|
||||||
|
display: block;
|
||||||
|
transition: $transition-collapse;
|
||||||
|
}
|
||||||
|
.collapse,
|
||||||
|
.collapsing {
|
||||||
|
margin: 0 1rem;
|
||||||
|
}
|
||||||
|
.nav-link {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
padding: 1rem;
|
||||||
|
width: $sidebar-base-width;
|
||||||
|
i {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
margin-right: 0.25rem;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
// Accordion Arrow Icon
|
||||||
|
&[data-toggle="collapse"] {
|
||||||
|
&::after {
|
||||||
|
width: 1rem;
|
||||||
|
text-align: center;
|
||||||
|
float: right;
|
||||||
|
vertical-align: 0;
|
||||||
|
border: 0;
|
||||||
|
font-weight: 900;
|
||||||
|
content: '\f107';
|
||||||
|
font-family: 'Font Awesome 5 Free';
|
||||||
|
}
|
||||||
|
&.collapsed::after {
|
||||||
|
content: '\f105';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.sidebar-brand {
|
||||||
|
.sidebar-brand-icon i {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
.sidebar-brand-text {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.sidebar-heading {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
&.toggled {
|
||||||
|
overflow: visible;
|
||||||
|
width: $sidebar-collapsed-width !important;
|
||||||
|
.nav-item {
|
||||||
|
// Accordion
|
||||||
|
.collapse {
|
||||||
|
position: absolute;
|
||||||
|
left: calc(#{$sidebar-collapsed-width} + #{$grid-gutter-width} / 2);
|
||||||
|
z-index: 1;
|
||||||
|
top: 2px;
|
||||||
|
// Grow In Animation for Toggled State
|
||||||
|
animation-name: growIn;
|
||||||
|
animation-duration: 200ms;
|
||||||
|
animation-timing-function: transform cubic-bezier(.18,1.25,.4,1), opacity cubic-bezier(0,1,.4,1);
|
||||||
|
.collapse-inner {
|
||||||
|
box-shadow: $box-shadow;
|
||||||
|
border-radius: $border-radius;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.collapsing {
|
||||||
|
display: none;
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
.collapse,
|
||||||
|
.collapsing {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
.nav-link {
|
||||||
|
text-align: center;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
width: $sidebar-collapsed-width;
|
||||||
|
span {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
i {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
&[data-toggle="collapse"]::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.sidebar-brand {
|
||||||
|
.sidebar-brand-icon i {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
.sidebar-brand-text {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.sidebar-heading {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sidebar Color Variants
|
||||||
|
|
||||||
|
// Sidebar Light
|
||||||
|
.sidebar-light {
|
||||||
|
.sidebar-brand {
|
||||||
|
color: $gray-700;
|
||||||
|
}
|
||||||
|
hr.sidebar-divider {
|
||||||
|
border-top: 1px solid $gray-200;
|
||||||
|
}
|
||||||
|
.sidebar-heading {
|
||||||
|
color: $gray-500;
|
||||||
|
}
|
||||||
|
.nav-item {
|
||||||
|
.nav-link {
|
||||||
|
color: $gray-600;
|
||||||
|
i {
|
||||||
|
color: $gray-400;
|
||||||
|
}
|
||||||
|
&:active,
|
||||||
|
&:focus,
|
||||||
|
&:hover {
|
||||||
|
color: $gray-700;
|
||||||
|
i {
|
||||||
|
color: $gray-700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Accordion
|
||||||
|
&[data-toggle="collapse"]::after {
|
||||||
|
color: $gray-500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.active {
|
||||||
|
.nav-link {
|
||||||
|
color: $gray-700;
|
||||||
|
i {
|
||||||
|
color: $gray-700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Color the sidebar toggler
|
||||||
|
#sidebarToggle {
|
||||||
|
background-color: $gray-200;
|
||||||
|
&::after {
|
||||||
|
color: $gray-500;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
background-color: $gray-300;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sidebar Dark
|
||||||
|
.sidebar-dark {
|
||||||
|
.sidebar-brand {
|
||||||
|
color: $white;
|
||||||
|
}
|
||||||
|
hr.sidebar-divider {
|
||||||
|
border-top: 1px solid fade-out($white, 0.85);
|
||||||
|
}
|
||||||
|
.sidebar-heading {
|
||||||
|
color: fade-out($white, 0.6);
|
||||||
|
}
|
||||||
|
.nav-item {
|
||||||
|
.nav-link {
|
||||||
|
color: fade-out($white, 0.2);
|
||||||
|
i {
|
||||||
|
color: fade-out($white, 0.7);
|
||||||
|
}
|
||||||
|
&:active,
|
||||||
|
&:focus,
|
||||||
|
&:hover {
|
||||||
|
color: $white;
|
||||||
|
i {
|
||||||
|
color: $white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Accordion
|
||||||
|
&[data-toggle="collapse"]::after {
|
||||||
|
color: fade-out($white, 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.active {
|
||||||
|
.nav-link {
|
||||||
|
color: $white;
|
||||||
|
i {
|
||||||
|
color: $white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Color the sidebar toggler
|
||||||
|
#sidebarToggle {
|
||||||
|
background-color: fade-out($white, 0.8);
|
||||||
|
&::after {
|
||||||
|
color: fade-out($white, 0.5);
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
background-color: fade-out($white, 0.75);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.toggled {
|
||||||
|
#sidebarToggle::after {
|
||||||
|
color: fade-out($white, 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,144 @@
|
||||||
|
// Topbar
|
||||||
|
.topbar {
|
||||||
|
height: $topbar-base-height;
|
||||||
|
#sidebarToggleTop {
|
||||||
|
height: 2.5rem;
|
||||||
|
width: 2.5rem;
|
||||||
|
&:hover {
|
||||||
|
background-color: $gray-200;
|
||||||
|
}
|
||||||
|
&:active {
|
||||||
|
background-color: $gray-300;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.navbar-search {
|
||||||
|
width: 25rem;
|
||||||
|
input {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.topbar-divider {
|
||||||
|
width: 0;
|
||||||
|
border-right: 1px solid $border-color;
|
||||||
|
height: calc(#{$topbar-base-height} - 2rem);
|
||||||
|
margin: auto 1rem;
|
||||||
|
}
|
||||||
|
.nav-item {
|
||||||
|
.nav-link {
|
||||||
|
height: $topbar-base-height;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 0.75rem;
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.dropdown {
|
||||||
|
position: static;
|
||||||
|
.dropdown-menu {
|
||||||
|
width: calc(100% - #{$grid-gutter-width});
|
||||||
|
right: $grid-gutter-width / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.dropdown-list {
|
||||||
|
padding: 0;
|
||||||
|
border: none;
|
||||||
|
overflow: hidden;
|
||||||
|
.dropdown-header {
|
||||||
|
background-color: $primary;
|
||||||
|
border: 1px solid $primary;
|
||||||
|
padding-top: 0.75rem;
|
||||||
|
padding-bottom: 0.75rem;
|
||||||
|
color: $white;
|
||||||
|
}
|
||||||
|
.dropdown-item {
|
||||||
|
white-space: normal;
|
||||||
|
padding-top: 0.5rem;
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
border-left: 1px solid $border-color;
|
||||||
|
border-right: 1px solid $border-color;
|
||||||
|
border-bottom: 1px solid $border-color;
|
||||||
|
line-height: 1.3rem;
|
||||||
|
.dropdown-list-image {
|
||||||
|
position: relative;
|
||||||
|
height: 2.5rem;
|
||||||
|
width: 2.5rem;
|
||||||
|
img {
|
||||||
|
height: 2.5rem;
|
||||||
|
width: 2.5rem;
|
||||||
|
}
|
||||||
|
.status-indicator {
|
||||||
|
background-color: $gray-200;
|
||||||
|
height: 0.75rem;
|
||||||
|
width: 0.75rem;
|
||||||
|
border-radius: 100%;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
border: .125rem solid $white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.text-truncate {
|
||||||
|
max-width: 10rem;
|
||||||
|
}
|
||||||
|
&:active {
|
||||||
|
background-color: $gray-200;
|
||||||
|
color: $gray-900;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@include media-breakpoint-up(sm) {
|
||||||
|
.dropdown {
|
||||||
|
position: relative;
|
||||||
|
.dropdown-menu {
|
||||||
|
width: auto;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.dropdown-list {
|
||||||
|
width: 20rem !important;
|
||||||
|
.dropdown-item {
|
||||||
|
.text-truncate {
|
||||||
|
max-width: 13.375rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar.navbar-dark {
|
||||||
|
.navbar-nav {
|
||||||
|
.nav-item {
|
||||||
|
.nav-link {
|
||||||
|
color: fade-out($white, 0.2);
|
||||||
|
&:hover {
|
||||||
|
color: $white;
|
||||||
|
}
|
||||||
|
&:active {
|
||||||
|
color: $white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar.navbar-light {
|
||||||
|
.navbar-nav {
|
||||||
|
.nav-item {
|
||||||
|
.nav-link {
|
||||||
|
color: $gray-400;
|
||||||
|
&:hover {
|
||||||
|
color: $gray-500;
|
||||||
|
}
|
||||||
|
&:active {
|
||||||
|
color: $gray-600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
// Import Custom SB Admin 2 Variables (Overrides Default Bootstrap Variables)
|
||||||
|
@import "variables.scss";
|
||||||
|
|
||||||
|
// Import Bootstrap
|
||||||
|
@import "../vendor/bootstrap/scss/bootstrap.scss";
|
||||||
|
|
||||||
|
// Import Custom SB Admin 2 Mixins and Components
|
||||||
|
@import "mixins.scss";
|
||||||
|
@import "global.scss";
|
||||||
|
@import "utilities.scss";
|
||||||
|
|
||||||
|
// Custom Components
|
||||||
|
@import "dropdowns.scss";
|
||||||
|
@import "navs.scss";
|
||||||
|
@import "buttons.scss";
|
||||||
|
@import "cards.scss";
|
||||||
|
@import "charts.scss";
|
||||||
|
@import "login.scss";
|
||||||
|
@import "error.scss";
|
||||||
|
@import "footer.scss";
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
// Animation Utilities
|
||||||
|
|
||||||
|
// Grow In Animation
|
||||||
|
|
||||||
|
@keyframes growIn {
|
||||||
|
0% {
|
||||||
|
transform: scale(0.9);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animated--grow-in {
|
||||||
|
animation-name: growIn;
|
||||||
|
animation-duration: 200ms;
|
||||||
|
animation-timing-function: transform cubic-bezier(.18,1.25,.4,1), opacity cubic-bezier(0,1,.4,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fade In Animation
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animated--fade-in {
|
||||||
|
animation-name: fadeIn;
|
||||||
|
animation-duration: 200ms;
|
||||||
|
animation-timing-function: opacity cubic-bezier(0,1,.4,1);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
// Background Gradient Utilities
|
||||||
|
|
||||||
|
@each $color, $value in $theme-colors {
|
||||||
|
.bg-gradient-#{$color} {
|
||||||
|
background-color: $value;
|
||||||
|
background-image: linear-gradient(180deg, $value 10%, darken($value, 15%) 100%);
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grayscale Background Utilities
|
||||||
|
|
||||||
|
@each $level, $value in $grays {
|
||||||
|
.bg-gray-#{$level} {
|
||||||
|
background-color: $value !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
@each $color, $value in $theme-colors {
|
||||||
|
@each $position in ['left', 'bottom'] {
|
||||||
|
.border-#{$position}-#{$color} {
|
||||||
|
border-#{$position}: .25rem solid $value !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
// Overflow Hidden
|
||||||
|
.o-hidden {
|
||||||
|
overflow: hidden !important;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
.progress-sm {
|
||||||
|
height: .5rem;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
.rotate-15 {
|
||||||
|
transform: rotate(15deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rotate-n-15 {
|
||||||
|
transform: rotate(-15deg);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
// Grayscale Text Utilities
|
||||||
|
|
||||||
|
.text-xs {
|
||||||
|
font-size: .7rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-lg {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-gray-100 {
|
||||||
|
color: $gray-100 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-gray-200 {
|
||||||
|
color: $gray-200 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-gray-300 {
|
||||||
|
color: $gray-300 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-gray-400 {
|
||||||
|
color: $gray-400 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-gray-500 {
|
||||||
|
color: $gray-500 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-gray-600 {
|
||||||
|
color: $gray-600 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-gray-700 {
|
||||||
|
color: $gray-700 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-gray-800 {
|
||||||
|
color: $gray-800 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-gray-900 {
|
||||||
|
color: $gray-900 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-circle {
|
||||||
|
height: 2.5rem;
|
||||||
|
width: 2.5rem;
|
||||||
|
border-radius: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,51 @@
|
||||||
|
//
|
||||||
|
// Base styles
|
||||||
|
//
|
||||||
|
|
||||||
|
.alert {
|
||||||
|
position: relative;
|
||||||
|
padding: $alert-padding-y $alert-padding-x;
|
||||||
|
margin-bottom: $alert-margin-bottom;
|
||||||
|
border: $alert-border-width solid transparent;
|
||||||
|
@include border-radius($alert-border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Headings for larger alerts
|
||||||
|
.alert-heading {
|
||||||
|
// Specified to prevent conflicts of changing $headings-color
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Provide class for links that match alerts
|
||||||
|
.alert-link {
|
||||||
|
font-weight: $alert-link-font-weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Dismissible alerts
|
||||||
|
//
|
||||||
|
// Expand the right padding and account for the close button's positioning.
|
||||||
|
|
||||||
|
.alert-dismissible {
|
||||||
|
padding-right: $close-font-size + $alert-padding-x * 2;
|
||||||
|
|
||||||
|
// Adjust close link position
|
||||||
|
.close {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
padding: $alert-padding-y $alert-padding-x;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Alternate styles
|
||||||
|
//
|
||||||
|
// Generate contextual modifier classes for colorizing the alert.
|
||||||
|
|
||||||
|
@each $color, $value in $theme-colors {
|
||||||
|
.alert-#{$color} {
|
||||||
|
@include alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
// Base class
|
||||||
|
//
|
||||||
|
// Requires one of the contextual, color modifier classes for `color` and
|
||||||
|
// `background-color`.
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
display: inline-block;
|
||||||
|
padding: $badge-padding-y $badge-padding-x;
|
||||||
|
@include font-size($badge-font-size);
|
||||||
|
font-weight: $badge-font-weight;
|
||||||
|
line-height: 1;
|
||||||
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
vertical-align: baseline;
|
||||||
|
@include border-radius($badge-border-radius);
|
||||||
|
@include transition($badge-transition);
|
||||||
|
|
||||||
|
@at-root a#{&} {
|
||||||
|
@include hover-focus() {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Empty badges collapse automatically
|
||||||
|
&:empty {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Quick fix for badges in buttons
|
||||||
|
.btn .badge {
|
||||||
|
position: relative;
|
||||||
|
top: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pill badges
|
||||||
|
//
|
||||||
|
// Make them extra rounded with a modifier to replace v3's badges.
|
||||||
|
|
||||||
|
.badge-pill {
|
||||||
|
padding-right: $badge-pill-padding-x;
|
||||||
|
padding-left: $badge-pill-padding-x;
|
||||||
|
@include border-radius($badge-pill-border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Colors
|
||||||
|
//
|
||||||
|
// Contextual variations (linked badges get darker on :hover).
|
||||||
|
|
||||||
|
@each $color, $value in $theme-colors {
|
||||||
|
.badge-#{$color} {
|
||||||
|
@include badge-variant($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
.breadcrumb {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
padding: $breadcrumb-padding-y $breadcrumb-padding-x;
|
||||||
|
margin-bottom: $breadcrumb-margin-bottom;
|
||||||
|
@include font-size($breadcrumb-font-size);
|
||||||
|
list-style: none;
|
||||||
|
background-color: $breadcrumb-bg;
|
||||||
|
@include border-radius($breadcrumb-border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb-item {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
// The separator between breadcrumbs (by default, a forward-slash: "/")
|
||||||
|
+ .breadcrumb-item {
|
||||||
|
padding-left: $breadcrumb-item-padding;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
display: inline-block; // Suppress underlining of the separator in modern browsers
|
||||||
|
padding-right: $breadcrumb-item-padding;
|
||||||
|
color: $breadcrumb-divider-color;
|
||||||
|
content: escape-svg($breadcrumb-divider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built
|
||||||
|
// without `<ul>`s. The `::before` pseudo-element generates an element
|
||||||
|
// *within* the .breadcrumb-item and thereby inherits the `text-decoration`.
|
||||||
|
//
|
||||||
|
// To trick IE into suppressing the underline, we give the pseudo-element an
|
||||||
|
// underline and then immediately remove it.
|
||||||
|
+ .breadcrumb-item:hover::before {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
// stylelint-disable-next-line no-duplicate-selectors
|
||||||
|
+ .breadcrumb-item:hover::before {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: $breadcrumb-active-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,163 @@
|
||||||
|
// stylelint-disable selector-no-qualifying-type
|
||||||
|
|
||||||
|
// Make the div behave like a button
|
||||||
|
.btn-group,
|
||||||
|
.btn-group-vertical {
|
||||||
|
position: relative;
|
||||||
|
display: inline-flex;
|
||||||
|
vertical-align: middle; // match .btn alignment given font-size hack above
|
||||||
|
|
||||||
|
> .btn {
|
||||||
|
position: relative;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
|
||||||
|
// Bring the hover, focused, and "active" buttons to the front to overlay
|
||||||
|
// the borders properly
|
||||||
|
@include hover() {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
&:focus,
|
||||||
|
&:active,
|
||||||
|
&.active {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optional: Group multiple button groups together for a toolbar
|
||||||
|
.btn-toolbar {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: flex-start;
|
||||||
|
|
||||||
|
.input-group {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group {
|
||||||
|
// Prevent double borders when buttons are next to each other
|
||||||
|
> .btn:not(:first-child),
|
||||||
|
> .btn-group:not(:first-child) {
|
||||||
|
margin-left: -$btn-border-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset rounded corners
|
||||||
|
> .btn:not(:last-child):not(.dropdown-toggle),
|
||||||
|
> .btn-group:not(:last-child) > .btn {
|
||||||
|
@include border-right-radius(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
> .btn:not(:first-child),
|
||||||
|
> .btn-group:not(:first-child) > .btn {
|
||||||
|
@include border-left-radius(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sizing
|
||||||
|
//
|
||||||
|
// Remix the default button sizing classes into new ones for easier manipulation.
|
||||||
|
|
||||||
|
.btn-group-sm > .btn { @extend .btn-sm; }
|
||||||
|
.btn-group-lg > .btn { @extend .btn-lg; }
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Split button dropdowns
|
||||||
|
//
|
||||||
|
|
||||||
|
.dropdown-toggle-split {
|
||||||
|
padding-right: $btn-padding-x * .75;
|
||||||
|
padding-left: $btn-padding-x * .75;
|
||||||
|
|
||||||
|
&::after,
|
||||||
|
.dropup &::after,
|
||||||
|
.dropright &::after {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropleft &::before {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sm + .dropdown-toggle-split {
|
||||||
|
padding-right: $btn-padding-x-sm * .75;
|
||||||
|
padding-left: $btn-padding-x-sm * .75;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-lg + .dropdown-toggle-split {
|
||||||
|
padding-right: $btn-padding-x-lg * .75;
|
||||||
|
padding-left: $btn-padding-x-lg * .75;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// The clickable button for toggling the menu
|
||||||
|
// Set the same inset shadow as the :active state
|
||||||
|
.btn-group.show .dropdown-toggle {
|
||||||
|
@include box-shadow($btn-active-box-shadow);
|
||||||
|
|
||||||
|
// Show no shadow for `.btn-link` since it has no other button styles.
|
||||||
|
&.btn-link {
|
||||||
|
@include box-shadow(none);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Vertical button groups
|
||||||
|
//
|
||||||
|
|
||||||
|
.btn-group-vertical {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
> .btn,
|
||||||
|
> .btn-group {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .btn:not(:first-child),
|
||||||
|
> .btn-group:not(:first-child) {
|
||||||
|
margin-top: -$btn-border-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset rounded corners
|
||||||
|
> .btn:not(:last-child):not(.dropdown-toggle),
|
||||||
|
> .btn-group:not(:last-child) > .btn {
|
||||||
|
@include border-bottom-radius(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
> .btn:not(:first-child),
|
||||||
|
> .btn-group:not(:first-child) > .btn {
|
||||||
|
@include border-top-radius(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Checkbox and radio options
|
||||||
|
//
|
||||||
|
// In order to support the browser's form validation feedback, powered by the
|
||||||
|
// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use
|
||||||
|
// `display: none;` or `visibility: hidden;` as that also hides the popover.
|
||||||
|
// Simply visually hiding the inputs via `opacity` would leave them clickable in
|
||||||
|
// certain cases which is prevented by using `clip` and `pointer-events`.
|
||||||
|
// This way, we ensure a DOM element is visible to position the popover from.
|
||||||
|
//
|
||||||
|
// See https://github.com/twbs/bootstrap/pull/12794 and
|
||||||
|
// https://github.com/twbs/bootstrap/pull/14559 for more information.
|
||||||
|
|
||||||
|
.btn-group-toggle {
|
||||||
|
> .btn,
|
||||||
|
> .btn-group > .btn {
|
||||||
|
margin-bottom: 0; // Override default `<label>` value
|
||||||
|
|
||||||
|
input[type="radio"],
|
||||||
|
input[type="checkbox"] {
|
||||||
|
position: absolute;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,142 @@
|
||||||
|
// stylelint-disable selector-no-qualifying-type
|
||||||
|
|
||||||
|
//
|
||||||
|
// Base styles
|
||||||
|
//
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
display: inline-block;
|
||||||
|
font-family: $btn-font-family;
|
||||||
|
font-weight: $btn-font-weight;
|
||||||
|
color: $body-color;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: if($link-decoration == none, null, none);
|
||||||
|
white-space: $btn-white-space;
|
||||||
|
vertical-align: middle;
|
||||||
|
user-select: none;
|
||||||
|
background-color: transparent;
|
||||||
|
border: $btn-border-width solid transparent;
|
||||||
|
@include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-line-height, $btn-border-radius);
|
||||||
|
@include transition($btn-transition);
|
||||||
|
|
||||||
|
@include hover() {
|
||||||
|
color: $body-color;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus,
|
||||||
|
&.focus {
|
||||||
|
outline: 0;
|
||||||
|
box-shadow: $btn-focus-box-shadow;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disabled comes first so active can properly restyle
|
||||||
|
&.disabled,
|
||||||
|
&:disabled {
|
||||||
|
opacity: $btn-disabled-opacity;
|
||||||
|
@include box-shadow(none);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:disabled):not(.disabled) {
|
||||||
|
cursor: if($enable-pointer-cursor-for-buttons, pointer, null);
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&.active {
|
||||||
|
@include box-shadow($btn-active-box-shadow);
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
@include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Future-proof disabling of clicks on `<a>` elements
|
||||||
|
a.btn.disabled,
|
||||||
|
fieldset:disabled a.btn {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Alternate buttons
|
||||||
|
//
|
||||||
|
|
||||||
|
@each $color, $value in $theme-colors {
|
||||||
|
.btn-#{$color} {
|
||||||
|
@include button-variant($value, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $color, $value in $theme-colors {
|
||||||
|
.btn-outline-#{$color} {
|
||||||
|
@include button-outline-variant($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Link buttons
|
||||||
|
//
|
||||||
|
|
||||||
|
// Make a button look and behave like a link
|
||||||
|
.btn-link {
|
||||||
|
font-weight: $font-weight-normal;
|
||||||
|
color: $link-color;
|
||||||
|
text-decoration: $link-decoration;
|
||||||
|
|
||||||
|
@include hover() {
|
||||||
|
color: $link-hover-color;
|
||||||
|
text-decoration: $link-hover-decoration;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus,
|
||||||
|
&.focus {
|
||||||
|
text-decoration: $link-hover-decoration;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled,
|
||||||
|
&.disabled {
|
||||||
|
color: $btn-link-disabled-color;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No need for an active state here
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Button Sizes
|
||||||
|
//
|
||||||
|
|
||||||
|
.btn-lg {
|
||||||
|
@include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-line-height-lg, $btn-border-radius-lg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sm {
|
||||||
|
@include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-line-height-sm, $btn-border-radius-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Block button
|
||||||
|
//
|
||||||
|
|
||||||
|
.btn-block {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
// Vertically space out multiple block buttons
|
||||||
|
+ .btn-block {
|
||||||
|
margin-top: $btn-block-spacing-y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Specificity overrides
|
||||||
|
input[type="submit"],
|
||||||
|
input[type="reset"],
|
||||||
|
input[type="button"] {
|
||||||
|
&.btn-block {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,282 @@
|
||||||
|
//
|
||||||
|
// Base styles
|
||||||
|
//
|
||||||
|
|
||||||
|
.card {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106
|
||||||
|
height: $card-height;
|
||||||
|
word-wrap: break-word;
|
||||||
|
background-color: $card-bg;
|
||||||
|
background-clip: border-box;
|
||||||
|
border: $card-border-width solid $card-border-color;
|
||||||
|
@include border-radius($card-border-radius);
|
||||||
|
|
||||||
|
> hr {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .list-group {
|
||||||
|
border-top: inherit;
|
||||||
|
border-bottom: inherit;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
border-top-width: 0;
|
||||||
|
@include border-top-radius($card-inner-border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom-width: 0;
|
||||||
|
@include border-bottom-radius($card-inner-border-radius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-body {
|
||||||
|
// Enable `flex-grow: 1` for decks and groups so that card blocks take up
|
||||||
|
// as much space as possible, ensuring footers are aligned to the bottom.
|
||||||
|
flex: 1 1 auto;
|
||||||
|
// Workaround for the image size bug in IE
|
||||||
|
// See: https://github.com/twbs/bootstrap/pull/28855
|
||||||
|
min-height: 1px;
|
||||||
|
padding: $card-spacer-x;
|
||||||
|
color: $card-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-title {
|
||||||
|
margin-bottom: $card-spacer-y;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-subtitle {
|
||||||
|
margin-top: -$card-spacer-y / 2;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-text:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-link {
|
||||||
|
@include hover() {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ .card-link {
|
||||||
|
margin-left: $card-spacer-x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Optional textual caps
|
||||||
|
//
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
padding: $card-spacer-y $card-spacer-x;
|
||||||
|
margin-bottom: 0; // Removes the default margin-bottom of <hN>
|
||||||
|
color: $card-cap-color;
|
||||||
|
background-color: $card-cap-bg;
|
||||||
|
border-bottom: $card-border-width solid $card-border-color;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
@include border-radius($card-inner-border-radius $card-inner-border-radius 0 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ .list-group {
|
||||||
|
.list-group-item:first-child {
|
||||||
|
border-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-footer {
|
||||||
|
padding: $card-spacer-y $card-spacer-x;
|
||||||
|
color: $card-cap-color;
|
||||||
|
background-color: $card-cap-bg;
|
||||||
|
border-top: $card-border-width solid $card-border-color;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
@include border-radius(0 0 $card-inner-border-radius $card-inner-border-radius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Header navs
|
||||||
|
//
|
||||||
|
|
||||||
|
.card-header-tabs {
|
||||||
|
margin-right: -$card-spacer-x / 2;
|
||||||
|
margin-bottom: -$card-spacer-y;
|
||||||
|
margin-left: -$card-spacer-x / 2;
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header-pills {
|
||||||
|
margin-right: -$card-spacer-x / 2;
|
||||||
|
margin-left: -$card-spacer-x / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Card image
|
||||||
|
.card-img-overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: $card-img-overlay-padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-img,
|
||||||
|
.card-img-top,
|
||||||
|
.card-img-bottom {
|
||||||
|
flex-shrink: 0; // For IE: https://github.com/twbs/bootstrap/issues/29396
|
||||||
|
width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-img,
|
||||||
|
.card-img-top {
|
||||||
|
@include border-top-radius($card-inner-border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-img,
|
||||||
|
.card-img-bottom {
|
||||||
|
@include border-bottom-radius($card-inner-border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Card deck
|
||||||
|
|
||||||
|
.card-deck {
|
||||||
|
.card {
|
||||||
|
margin-bottom: $card-deck-margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-breakpoint-up(sm) {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row wrap;
|
||||||
|
margin-right: -$card-deck-margin;
|
||||||
|
margin-left: -$card-deck-margin;
|
||||||
|
|
||||||
|
.card {
|
||||||
|
// Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4
|
||||||
|
flex: 1 0 0%;
|
||||||
|
margin-right: $card-deck-margin;
|
||||||
|
margin-bottom: 0; // Override the default
|
||||||
|
margin-left: $card-deck-margin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Card groups
|
||||||
|
//
|
||||||
|
|
||||||
|
.card-group {
|
||||||
|
// The child selector allows nested `.card` within `.card-group`
|
||||||
|
// to display properly.
|
||||||
|
> .card {
|
||||||
|
margin-bottom: $card-group-margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-breakpoint-up(sm) {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row wrap;
|
||||||
|
// The child selector allows nested `.card` within `.card-group`
|
||||||
|
// to display properly.
|
||||||
|
> .card {
|
||||||
|
// Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4
|
||||||
|
flex: 1 0 0%;
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
+ .card {
|
||||||
|
margin-left: 0;
|
||||||
|
border-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle rounded corners
|
||||||
|
@if $enable-rounded {
|
||||||
|
&:not(:last-child) {
|
||||||
|
@include border-right-radius(0);
|
||||||
|
|
||||||
|
.card-img-top,
|
||||||
|
.card-header {
|
||||||
|
// stylelint-disable-next-line property-blacklist
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
}
|
||||||
|
.card-img-bottom,
|
||||||
|
.card-footer {
|
||||||
|
// stylelint-disable-next-line property-blacklist
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:first-child) {
|
||||||
|
@include border-left-radius(0);
|
||||||
|
|
||||||
|
.card-img-top,
|
||||||
|
.card-header {
|
||||||
|
// stylelint-disable-next-line property-blacklist
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
}
|
||||||
|
.card-img-bottom,
|
||||||
|
.card-footer {
|
||||||
|
// stylelint-disable-next-line property-blacklist
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Columns
|
||||||
|
//
|
||||||
|
|
||||||
|
.card-columns {
|
||||||
|
.card {
|
||||||
|
margin-bottom: $card-columns-margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-breakpoint-up(sm) {
|
||||||
|
column-count: $card-columns-count;
|
||||||
|
column-gap: $card-columns-gap;
|
||||||
|
orphans: 1;
|
||||||
|
widows: 1;
|
||||||
|
|
||||||
|
.card {
|
||||||
|
display: inline-block; // Don't let them vertically span multiple columns
|
||||||
|
width: 100%; // Don't let their width change
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Accordion
|
||||||
|
//
|
||||||
|
|
||||||
|
.accordion {
|
||||||
|
> .card {
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&:not(:last-of-type) {
|
||||||
|
border-bottom: 0;
|
||||||
|
@include border-bottom-radius(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:first-of-type) {
|
||||||
|
@include border-top-radius(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
> .card-header {
|
||||||
|
@include border-radius(0);
|
||||||
|
margin-bottom: -$card-border-width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,197 @@
|
||||||
|
// Notes on the classes:
|
||||||
|
//
|
||||||
|
// 1. .carousel.pointer-event should ideally be pan-y (to allow for users to scroll vertically)
|
||||||
|
// even when their scroll action started on a carousel, but for compatibility (with Firefox)
|
||||||
|
// we're preventing all actions instead
|
||||||
|
// 2. The .carousel-item-left and .carousel-item-right is used to indicate where
|
||||||
|
// the active slide is heading.
|
||||||
|
// 3. .active.carousel-item is the current slide.
|
||||||
|
// 4. .active.carousel-item-left and .active.carousel-item-right is the current
|
||||||
|
// slide in its in-transition state. Only one of these occurs at a time.
|
||||||
|
// 5. .carousel-item-next.carousel-item-left and .carousel-item-prev.carousel-item-right
|
||||||
|
// is the upcoming slide in transition.
|
||||||
|
|
||||||
|
.carousel {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel.pointer-event {
|
||||||
|
touch-action: pan-y;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-inner {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
@include clearfix();
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-item {
|
||||||
|
position: relative;
|
||||||
|
display: none;
|
||||||
|
float: left;
|
||||||
|
width: 100%;
|
||||||
|
margin-right: -100%;
|
||||||
|
backface-visibility: hidden;
|
||||||
|
@include transition($carousel-transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-item.active,
|
||||||
|
.carousel-item-next,
|
||||||
|
.carousel-item-prev {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-item-next:not(.carousel-item-left),
|
||||||
|
.active.carousel-item-right {
|
||||||
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-item-prev:not(.carousel-item-right),
|
||||||
|
.active.carousel-item-left {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Alternate transitions
|
||||||
|
//
|
||||||
|
|
||||||
|
.carousel-fade {
|
||||||
|
.carousel-item {
|
||||||
|
opacity: 0;
|
||||||
|
transition-property: opacity;
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-item.active,
|
||||||
|
.carousel-item-next.carousel-item-left,
|
||||||
|
.carousel-item-prev.carousel-item-right {
|
||||||
|
z-index: 1;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active.carousel-item-left,
|
||||||
|
.active.carousel-item-right {
|
||||||
|
z-index: 0;
|
||||||
|
opacity: 0;
|
||||||
|
@include transition(opacity 0s $carousel-transition-duration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Left/right controls for nav
|
||||||
|
//
|
||||||
|
|
||||||
|
.carousel-control-prev,
|
||||||
|
.carousel-control-next {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 1;
|
||||||
|
// Use flex for alignment (1-3)
|
||||||
|
display: flex; // 1. allow flex styles
|
||||||
|
align-items: center; // 2. vertically center contents
|
||||||
|
justify-content: center; // 3. horizontally center contents
|
||||||
|
width: $carousel-control-width;
|
||||||
|
color: $carousel-control-color;
|
||||||
|
text-align: center;
|
||||||
|
opacity: $carousel-control-opacity;
|
||||||
|
@include transition($carousel-control-transition);
|
||||||
|
|
||||||
|
// Hover/focus state
|
||||||
|
@include hover-focus() {
|
||||||
|
color: $carousel-control-color;
|
||||||
|
text-decoration: none;
|
||||||
|
outline: 0;
|
||||||
|
opacity: $carousel-control-hover-opacity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.carousel-control-prev {
|
||||||
|
left: 0;
|
||||||
|
@if $enable-gradients {
|
||||||
|
background-image: linear-gradient(90deg, rgba($black, .25), rgba($black, .001));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.carousel-control-next {
|
||||||
|
right: 0;
|
||||||
|
@if $enable-gradients {
|
||||||
|
background-image: linear-gradient(270deg, rgba($black, .25), rgba($black, .001));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Icons for within
|
||||||
|
.carousel-control-prev-icon,
|
||||||
|
.carousel-control-next-icon {
|
||||||
|
display: inline-block;
|
||||||
|
width: $carousel-control-icon-width;
|
||||||
|
height: $carousel-control-icon-width;
|
||||||
|
background: no-repeat 50% / 100% 100%;
|
||||||
|
}
|
||||||
|
.carousel-control-prev-icon {
|
||||||
|
background-image: escape-svg($carousel-control-prev-icon-bg);
|
||||||
|
}
|
||||||
|
.carousel-control-next-icon {
|
||||||
|
background-image: escape-svg($carousel-control-next-icon-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Optional indicator pips
|
||||||
|
//
|
||||||
|
// Add an ordered list with the following class and add a list item for each
|
||||||
|
// slide your carousel holds.
|
||||||
|
|
||||||
|
.carousel-indicators {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 15;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
padding-left: 0; // override <ol> default
|
||||||
|
// Use the .carousel-control's width as margin so we don't overlay those
|
||||||
|
margin-right: $carousel-control-width;
|
||||||
|
margin-left: $carousel-control-width;
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
box-sizing: content-box;
|
||||||
|
flex: 0 1 auto;
|
||||||
|
width: $carousel-indicator-width;
|
||||||
|
height: $carousel-indicator-height;
|
||||||
|
margin-right: $carousel-indicator-spacer;
|
||||||
|
margin-left: $carousel-indicator-spacer;
|
||||||
|
text-indent: -999px;
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: $carousel-indicator-active-bg;
|
||||||
|
background-clip: padding-box;
|
||||||
|
// Use transparent borders to increase the hit area by 10px on top and bottom.
|
||||||
|
border-top: $carousel-indicator-hit-area-height solid transparent;
|
||||||
|
border-bottom: $carousel-indicator-hit-area-height solid transparent;
|
||||||
|
opacity: .5;
|
||||||
|
@include transition($carousel-indicator-transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.active {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Optional captions
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
.carousel-caption {
|
||||||
|
position: absolute;
|
||||||
|
right: (100% - $carousel-caption-width) / 2;
|
||||||
|
bottom: 20px;
|
||||||
|
left: (100% - $carousel-caption-width) / 2;
|
||||||
|
z-index: 10;
|
||||||
|
padding-top: 20px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
color: $carousel-caption-color;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
.close {
|
||||||
|
float: right;
|
||||||
|
@include font-size($close-font-size);
|
||||||
|
font-weight: $close-font-weight;
|
||||||
|
line-height: 1;
|
||||||
|
color: $close-color;
|
||||||
|
text-shadow: $close-text-shadow;
|
||||||
|
opacity: .5;
|
||||||
|
|
||||||
|
// Override <a>'s hover style
|
||||||
|
@include hover() {
|
||||||
|
color: $close-color;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:disabled):not(.disabled) {
|
||||||
|
@include hover-focus() {
|
||||||
|
opacity: .75;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Additional properties for button version
|
||||||
|
// iOS requires the button element instead of an anchor tag.
|
||||||
|
// If you want the anchor version, it requires `href="#"`.
|
||||||
|
// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
|
||||||
|
|
||||||
|
// stylelint-disable-next-line selector-no-qualifying-type
|
||||||
|
button.close {
|
||||||
|
padding: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Future-proof disabling of clicks on `<a>` elements
|
||||||
|
|
||||||
|
// stylelint-disable-next-line selector-no-qualifying-type
|
||||||
|
a.close.disabled {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
// Inline code
|
||||||
|
code {
|
||||||
|
@include font-size($code-font-size);
|
||||||
|
color: $code-color;
|
||||||
|
word-wrap: break-word;
|
||||||
|
|
||||||
|
// Streamline the style when inside anchors to avoid broken underline and more
|
||||||
|
a > & {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// User input typically entered via keyboard
|
||||||
|
kbd {
|
||||||
|
padding: $kbd-padding-y $kbd-padding-x;
|
||||||
|
@include font-size($kbd-font-size);
|
||||||
|
color: $kbd-color;
|
||||||
|
background-color: $kbd-bg;
|
||||||
|
@include border-radius($border-radius-sm);
|
||||||
|
@include box-shadow($kbd-box-shadow);
|
||||||
|
|
||||||
|
kbd {
|
||||||
|
padding: 0;
|
||||||
|
@include font-size(100%);
|
||||||
|
font-weight: $nested-kbd-font-weight;
|
||||||
|
@include box-shadow(none);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blocks of code
|
||||||
|
pre {
|
||||||
|
display: block;
|
||||||
|
@include font-size($code-font-size);
|
||||||
|
color: $pre-color;
|
||||||
|
|
||||||
|
// Account for some code outputs that place code tags in pre tags
|
||||||
|
code {
|
||||||
|
@include font-size(inherit);
|
||||||
|
color: inherit;
|
||||||
|
word-break: normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable scrollable blocks of code
|
||||||
|
.pre-scrollable {
|
||||||
|
max-height: $pre-scrollable-max-height;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,522 @@
|
||||||
|
// Embedded icons from Open Iconic.
|
||||||
|
// Released under MIT and copyright 2014 Waybury.
|
||||||
|
// https://useiconic.com/open
|
||||||
|
|
||||||
|
|
||||||
|
// Checkboxes and radios
|
||||||
|
//
|
||||||
|
// Base class takes care of all the key behavioral aspects.
|
||||||
|
|
||||||
|
.custom-control {
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
min-height: $font-size-base * $line-height-base;
|
||||||
|
padding-left: $custom-control-gutter + $custom-control-indicator-size;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-control-inline {
|
||||||
|
display: inline-flex;
|
||||||
|
margin-right: $custom-control-spacer-x;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-control-input {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
z-index: -1; // Put the input behind the label so it doesn't overlay text
|
||||||
|
width: $custom-control-indicator-size;
|
||||||
|
height: ($font-size-base * $line-height-base + $custom-control-indicator-size) / 2;
|
||||||
|
opacity: 0;
|
||||||
|
|
||||||
|
&:checked ~ .custom-control-label::before {
|
||||||
|
color: $custom-control-indicator-checked-color;
|
||||||
|
border-color: $custom-control-indicator-checked-border-color;
|
||||||
|
@include gradient-bg($custom-control-indicator-checked-bg);
|
||||||
|
@include box-shadow($custom-control-indicator-checked-box-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus ~ .custom-control-label::before {
|
||||||
|
// the mixin is not used here to make sure there is feedback
|
||||||
|
@if $enable-shadows {
|
||||||
|
box-shadow: $input-box-shadow, $input-focus-box-shadow;
|
||||||
|
} @else {
|
||||||
|
box-shadow: $custom-control-indicator-focus-box-shadow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus:not(:checked) ~ .custom-control-label::before {
|
||||||
|
border-color: $custom-control-indicator-focus-border-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:disabled):active ~ .custom-control-label::before {
|
||||||
|
color: $custom-control-indicator-active-color;
|
||||||
|
background-color: $custom-control-indicator-active-bg;
|
||||||
|
border-color: $custom-control-indicator-active-border-color;
|
||||||
|
@include box-shadow($custom-control-indicator-active-box-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247
|
||||||
|
&[disabled],
|
||||||
|
&:disabled {
|
||||||
|
~ .custom-control-label {
|
||||||
|
color: $custom-control-label-disabled-color;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
background-color: $custom-control-indicator-disabled-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom control indicators
|
||||||
|
//
|
||||||
|
// Build the custom controls out of pseudo-elements.
|
||||||
|
|
||||||
|
.custom-control-label {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 0;
|
||||||
|
color: $custom-control-label-color;
|
||||||
|
vertical-align: top;
|
||||||
|
cursor: $custom-control-cursor;
|
||||||
|
|
||||||
|
// Background-color and (when enabled) gradient
|
||||||
|
&::before {
|
||||||
|
position: absolute;
|
||||||
|
top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;
|
||||||
|
left: -($custom-control-gutter + $custom-control-indicator-size);
|
||||||
|
display: block;
|
||||||
|
width: $custom-control-indicator-size;
|
||||||
|
height: $custom-control-indicator-size;
|
||||||
|
pointer-events: none;
|
||||||
|
content: "";
|
||||||
|
background-color: $custom-control-indicator-bg;
|
||||||
|
border: $custom-control-indicator-border-color solid $custom-control-indicator-border-width;
|
||||||
|
@include box-shadow($custom-control-indicator-box-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Foreground (icon)
|
||||||
|
&::after {
|
||||||
|
position: absolute;
|
||||||
|
top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;
|
||||||
|
left: -($custom-control-gutter + $custom-control-indicator-size);
|
||||||
|
display: block;
|
||||||
|
width: $custom-control-indicator-size;
|
||||||
|
height: $custom-control-indicator-size;
|
||||||
|
content: "";
|
||||||
|
background: no-repeat 50% / #{$custom-control-indicator-bg-size};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Checkboxes
|
||||||
|
//
|
||||||
|
// Tweak just a few things for checkboxes.
|
||||||
|
|
||||||
|
.custom-checkbox {
|
||||||
|
.custom-control-label::before {
|
||||||
|
@include border-radius($custom-checkbox-indicator-border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-control-input:checked ~ .custom-control-label {
|
||||||
|
&::after {
|
||||||
|
background-image: escape-svg($custom-checkbox-indicator-icon-checked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-control-input:indeterminate ~ .custom-control-label {
|
||||||
|
&::before {
|
||||||
|
border-color: $custom-checkbox-indicator-indeterminate-border-color;
|
||||||
|
@include gradient-bg($custom-checkbox-indicator-indeterminate-bg);
|
||||||
|
@include box-shadow($custom-checkbox-indicator-indeterminate-box-shadow);
|
||||||
|
}
|
||||||
|
&::after {
|
||||||
|
background-image: escape-svg($custom-checkbox-indicator-icon-indeterminate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-control-input:disabled {
|
||||||
|
&:checked ~ .custom-control-label::before {
|
||||||
|
background-color: $custom-control-indicator-checked-disabled-bg;
|
||||||
|
}
|
||||||
|
&:indeterminate ~ .custom-control-label::before {
|
||||||
|
background-color: $custom-control-indicator-checked-disabled-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Radios
|
||||||
|
//
|
||||||
|
// Tweak just a few things for radios.
|
||||||
|
|
||||||
|
.custom-radio {
|
||||||
|
.custom-control-label::before {
|
||||||
|
// stylelint-disable-next-line property-blacklist
|
||||||
|
border-radius: $custom-radio-indicator-border-radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-control-input:checked ~ .custom-control-label {
|
||||||
|
&::after {
|
||||||
|
background-image: escape-svg($custom-radio-indicator-icon-checked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-control-input:disabled {
|
||||||
|
&:checked ~ .custom-control-label::before {
|
||||||
|
background-color: $custom-control-indicator-checked-disabled-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// switches
|
||||||
|
//
|
||||||
|
// Tweak a few things for switches
|
||||||
|
|
||||||
|
.custom-switch {
|
||||||
|
padding-left: $custom-switch-width + $custom-control-gutter;
|
||||||
|
|
||||||
|
.custom-control-label {
|
||||||
|
&::before {
|
||||||
|
left: -($custom-switch-width + $custom-control-gutter);
|
||||||
|
width: $custom-switch-width;
|
||||||
|
pointer-events: all;
|
||||||
|
// stylelint-disable-next-line property-blacklist
|
||||||
|
border-radius: $custom-switch-indicator-border-radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
top: add(($font-size-base * $line-height-base - $custom-control-indicator-size) / 2, $custom-control-indicator-border-width * 2);
|
||||||
|
left: add(-($custom-switch-width + $custom-control-gutter), $custom-control-indicator-border-width * 2);
|
||||||
|
width: $custom-switch-indicator-size;
|
||||||
|
height: $custom-switch-indicator-size;
|
||||||
|
background-color: $custom-control-indicator-border-color;
|
||||||
|
// stylelint-disable-next-line property-blacklist
|
||||||
|
border-radius: $custom-switch-indicator-border-radius;
|
||||||
|
@include transition(transform .15s ease-in-out, $custom-forms-transition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-control-input:checked ~ .custom-control-label {
|
||||||
|
&::after {
|
||||||
|
background-color: $custom-control-indicator-bg;
|
||||||
|
transform: translateX($custom-switch-width - $custom-control-indicator-size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-control-input:disabled {
|
||||||
|
&:checked ~ .custom-control-label::before {
|
||||||
|
background-color: $custom-control-indicator-checked-disabled-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Select
|
||||||
|
//
|
||||||
|
// Replaces the browser default select with a custom one, mostly pulled from
|
||||||
|
// https://primer.github.io/.
|
||||||
|
//
|
||||||
|
|
||||||
|
.custom-select {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
height: $custom-select-height;
|
||||||
|
padding: $custom-select-padding-y ($custom-select-padding-x + $custom-select-indicator-padding) $custom-select-padding-y $custom-select-padding-x;
|
||||||
|
font-family: $custom-select-font-family;
|
||||||
|
@include font-size($custom-select-font-size);
|
||||||
|
font-weight: $custom-select-font-weight;
|
||||||
|
line-height: $custom-select-line-height;
|
||||||
|
color: $custom-select-color;
|
||||||
|
vertical-align: middle;
|
||||||
|
background: $custom-select-bg $custom-select-background;
|
||||||
|
border: $custom-select-border-width solid $custom-select-border-color;
|
||||||
|
@include border-radius($custom-select-border-radius, 0);
|
||||||
|
@include box-shadow($custom-select-box-shadow);
|
||||||
|
appearance: none;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border-color: $custom-select-focus-border-color;
|
||||||
|
outline: 0;
|
||||||
|
@if $enable-shadows {
|
||||||
|
@include box-shadow($custom-select-box-shadow, $custom-select-focus-box-shadow);
|
||||||
|
} @else {
|
||||||
|
// Avoid using mixin so we can pass custom focus shadow properly
|
||||||
|
box-shadow: $custom-select-focus-box-shadow;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-ms-value {
|
||||||
|
// For visual consistency with other platforms/browsers,
|
||||||
|
// suppress the default white text on blue background highlight given to
|
||||||
|
// the selected option text when the (still closed) <select> receives focus
|
||||||
|
// in IE and (under certain conditions) Edge.
|
||||||
|
// See https://github.com/twbs/bootstrap/issues/19398.
|
||||||
|
color: $input-color;
|
||||||
|
background-color: $input-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&[multiple],
|
||||||
|
&[size]:not([size="1"]) {
|
||||||
|
height: auto;
|
||||||
|
padding-right: $custom-select-padding-x;
|
||||||
|
background-image: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
color: $custom-select-disabled-color;
|
||||||
|
background-color: $custom-select-disabled-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hides the default caret in IE11
|
||||||
|
&::-ms-expand {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove outline from select box in FF
|
||||||
|
&:-moz-focusring {
|
||||||
|
color: transparent;
|
||||||
|
text-shadow: 0 0 0 $custom-select-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-select-sm {
|
||||||
|
height: $custom-select-height-sm;
|
||||||
|
padding-top: $custom-select-padding-y-sm;
|
||||||
|
padding-bottom: $custom-select-padding-y-sm;
|
||||||
|
padding-left: $custom-select-padding-x-sm;
|
||||||
|
@include font-size($custom-select-font-size-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-select-lg {
|
||||||
|
height: $custom-select-height-lg;
|
||||||
|
padding-top: $custom-select-padding-y-lg;
|
||||||
|
padding-bottom: $custom-select-padding-y-lg;
|
||||||
|
padding-left: $custom-select-padding-x-lg;
|
||||||
|
@include font-size($custom-select-font-size-lg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// File
|
||||||
|
//
|
||||||
|
// Custom file input.
|
||||||
|
|
||||||
|
.custom-file {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
height: $custom-file-height;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-file-input {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
width: 100%;
|
||||||
|
height: $custom-file-height;
|
||||||
|
margin: 0;
|
||||||
|
opacity: 0;
|
||||||
|
|
||||||
|
&:focus ~ .custom-file-label {
|
||||||
|
border-color: $custom-file-focus-border-color;
|
||||||
|
box-shadow: $custom-file-focus-box-shadow;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247
|
||||||
|
&[disabled] ~ .custom-file-label,
|
||||||
|
&:disabled ~ .custom-file-label {
|
||||||
|
background-color: $custom-file-disabled-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $lang, $value in $custom-file-text {
|
||||||
|
&:lang(#{$lang}) ~ .custom-file-label::after {
|
||||||
|
content: $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~ .custom-file-label[data-browse]::after {
|
||||||
|
content: attr(data-browse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-file-label {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1;
|
||||||
|
height: $custom-file-height;
|
||||||
|
padding: $custom-file-padding-y $custom-file-padding-x;
|
||||||
|
font-family: $custom-file-font-family;
|
||||||
|
font-weight: $custom-file-font-weight;
|
||||||
|
line-height: $custom-file-line-height;
|
||||||
|
color: $custom-file-color;
|
||||||
|
background-color: $custom-file-bg;
|
||||||
|
border: $custom-file-border-width solid $custom-file-border-color;
|
||||||
|
@include border-radius($custom-file-border-radius);
|
||||||
|
@include box-shadow($custom-file-box-shadow);
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 3;
|
||||||
|
display: block;
|
||||||
|
height: $custom-file-height-inner;
|
||||||
|
padding: $custom-file-padding-y $custom-file-padding-x;
|
||||||
|
line-height: $custom-file-line-height;
|
||||||
|
color: $custom-file-button-color;
|
||||||
|
content: "Browse";
|
||||||
|
@include gradient-bg($custom-file-button-bg);
|
||||||
|
border-left: inherit;
|
||||||
|
@include border-radius(0 $custom-file-border-radius $custom-file-border-radius 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Range
|
||||||
|
//
|
||||||
|
// Style range inputs the same across browsers. Vendor-specific rules for pseudo
|
||||||
|
// elements cannot be mixed. As such, there are no shared styles for focus or
|
||||||
|
// active states on prefixed selectors.
|
||||||
|
|
||||||
|
.custom-range {
|
||||||
|
width: 100%;
|
||||||
|
height: add($custom-range-thumb-height, $custom-range-thumb-focus-box-shadow-width * 2);
|
||||||
|
padding: 0; // Need to reset padding
|
||||||
|
background-color: transparent;
|
||||||
|
appearance: none;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
|
||||||
|
// Pseudo-elements must be split across multiple rulesets to have an effect.
|
||||||
|
// No box-shadow() mixin for focus accessibility.
|
||||||
|
&::-webkit-slider-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }
|
||||||
|
&::-moz-range-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }
|
||||||
|
&::-ms-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-moz-focus-outer {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-slider-thumb {
|
||||||
|
width: $custom-range-thumb-width;
|
||||||
|
height: $custom-range-thumb-height;
|
||||||
|
margin-top: ($custom-range-track-height - $custom-range-thumb-height) / 2; // Webkit specific
|
||||||
|
@include gradient-bg($custom-range-thumb-bg);
|
||||||
|
border: $custom-range-thumb-border;
|
||||||
|
@include border-radius($custom-range-thumb-border-radius);
|
||||||
|
@include box-shadow($custom-range-thumb-box-shadow);
|
||||||
|
@include transition($custom-forms-transition);
|
||||||
|
appearance: none;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
@include gradient-bg($custom-range-thumb-active-bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-slider-runnable-track {
|
||||||
|
width: $custom-range-track-width;
|
||||||
|
height: $custom-range-track-height;
|
||||||
|
color: transparent; // Why?
|
||||||
|
cursor: $custom-range-track-cursor;
|
||||||
|
background-color: $custom-range-track-bg;
|
||||||
|
border-color: transparent;
|
||||||
|
@include border-radius($custom-range-track-border-radius);
|
||||||
|
@include box-shadow($custom-range-track-box-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-moz-range-thumb {
|
||||||
|
width: $custom-range-thumb-width;
|
||||||
|
height: $custom-range-thumb-height;
|
||||||
|
@include gradient-bg($custom-range-thumb-bg);
|
||||||
|
border: $custom-range-thumb-border;
|
||||||
|
@include border-radius($custom-range-thumb-border-radius);
|
||||||
|
@include box-shadow($custom-range-thumb-box-shadow);
|
||||||
|
@include transition($custom-forms-transition);
|
||||||
|
appearance: none;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
@include gradient-bg($custom-range-thumb-active-bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-moz-range-track {
|
||||||
|
width: $custom-range-track-width;
|
||||||
|
height: $custom-range-track-height;
|
||||||
|
color: transparent;
|
||||||
|
cursor: $custom-range-track-cursor;
|
||||||
|
background-color: $custom-range-track-bg;
|
||||||
|
border-color: transparent; // Firefox specific?
|
||||||
|
@include border-radius($custom-range-track-border-radius);
|
||||||
|
@include box-shadow($custom-range-track-box-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-ms-thumb {
|
||||||
|
width: $custom-range-thumb-width;
|
||||||
|
height: $custom-range-thumb-height;
|
||||||
|
margin-top: 0; // Edge specific
|
||||||
|
margin-right: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.
|
||||||
|
margin-left: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.
|
||||||
|
@include gradient-bg($custom-range-thumb-bg);
|
||||||
|
border: $custom-range-thumb-border;
|
||||||
|
@include border-radius($custom-range-thumb-border-radius);
|
||||||
|
@include box-shadow($custom-range-thumb-box-shadow);
|
||||||
|
@include transition($custom-forms-transition);
|
||||||
|
appearance: none;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
@include gradient-bg($custom-range-thumb-active-bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-ms-track {
|
||||||
|
width: $custom-range-track-width;
|
||||||
|
height: $custom-range-track-height;
|
||||||
|
color: transparent;
|
||||||
|
cursor: $custom-range-track-cursor;
|
||||||
|
background-color: transparent;
|
||||||
|
border-color: transparent;
|
||||||
|
border-width: $custom-range-thumb-height / 2;
|
||||||
|
@include box-shadow($custom-range-track-box-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-ms-fill-lower {
|
||||||
|
background-color: $custom-range-track-bg;
|
||||||
|
@include border-radius($custom-range-track-border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-ms-fill-upper {
|
||||||
|
margin-right: 15px; // arbitrary?
|
||||||
|
background-color: $custom-range-track-bg;
|
||||||
|
@include border-radius($custom-range-track-border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
&::-webkit-slider-thumb {
|
||||||
|
background-color: $custom-range-thumb-disabled-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-slider-runnable-track {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-moz-range-thumb {
|
||||||
|
background-color: $custom-range-thumb-disabled-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-moz-range-track {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-ms-thumb {
|
||||||
|
background-color: $custom-range-thumb-disabled-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-control-label::before,
|
||||||
|
.custom-file-label,
|
||||||
|
.custom-select {
|
||||||
|
@include transition($custom-forms-transition);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,192 @@
|
||||||
|
// The dropdown wrapper (`<div>`)
|
||||||
|
.dropup,
|
||||||
|
.dropright,
|
||||||
|
.dropdown,
|
||||||
|
.dropleft {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-toggle {
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
// Generate the caret automatically
|
||||||
|
@include caret();
|
||||||
|
}
|
||||||
|
|
||||||
|
// The dropdown menu
|
||||||
|
.dropdown-menu {
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: 0;
|
||||||
|
z-index: $zindex-dropdown;
|
||||||
|
display: none; // none by default, but block on "open" of the menu
|
||||||
|
float: left;
|
||||||
|
min-width: $dropdown-min-width;
|
||||||
|
padding: $dropdown-padding-y 0;
|
||||||
|
margin: $dropdown-spacer 0 0; // override default ul
|
||||||
|
@include font-size($dropdown-font-size);
|
||||||
|
color: $dropdown-color;
|
||||||
|
text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)
|
||||||
|
list-style: none;
|
||||||
|
background-color: $dropdown-bg;
|
||||||
|
background-clip: padding-box;
|
||||||
|
border: $dropdown-border-width solid $dropdown-border-color;
|
||||||
|
@include border-radius($dropdown-border-radius);
|
||||||
|
@include box-shadow($dropdown-box-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $breakpoint in map-keys($grid-breakpoints) {
|
||||||
|
@include media-breakpoint-up($breakpoint) {
|
||||||
|
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
|
||||||
|
|
||||||
|
.dropdown-menu#{$infix}-left {
|
||||||
|
right: auto;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu#{$infix}-right {
|
||||||
|
right: 0;
|
||||||
|
left: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow for dropdowns to go bottom up (aka, dropup-menu)
|
||||||
|
// Just add .dropup after the standard .dropdown class and you're set.
|
||||||
|
.dropup {
|
||||||
|
.dropdown-menu {
|
||||||
|
top: auto;
|
||||||
|
bottom: 100%;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: $dropdown-spacer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-toggle {
|
||||||
|
@include caret(up);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropright {
|
||||||
|
.dropdown-menu {
|
||||||
|
top: 0;
|
||||||
|
right: auto;
|
||||||
|
left: 100%;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-left: $dropdown-spacer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-toggle {
|
||||||
|
@include caret(right);
|
||||||
|
&::after {
|
||||||
|
vertical-align: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropleft {
|
||||||
|
.dropdown-menu {
|
||||||
|
top: 0;
|
||||||
|
right: 100%;
|
||||||
|
left: auto;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-right: $dropdown-spacer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-toggle {
|
||||||
|
@include caret(left);
|
||||||
|
&::before {
|
||||||
|
vertical-align: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// When enabled Popper.js, reset basic dropdown position
|
||||||
|
// stylelint-disable-next-line no-duplicate-selectors
|
||||||
|
.dropdown-menu {
|
||||||
|
&[x-placement^="top"],
|
||||||
|
&[x-placement^="right"],
|
||||||
|
&[x-placement^="bottom"],
|
||||||
|
&[x-placement^="left"] {
|
||||||
|
right: auto;
|
||||||
|
bottom: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dividers (basically an `<hr>`) within the dropdown
|
||||||
|
.dropdown-divider {
|
||||||
|
@include nav-divider($dropdown-divider-bg, $dropdown-divider-margin-y, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Links, buttons, and more within the dropdown menu
|
||||||
|
//
|
||||||
|
// `<button>`-specific styles are denoted with `// For <button>s`
|
||||||
|
.dropdown-item {
|
||||||
|
display: block;
|
||||||
|
width: 100%; // For `<button>`s
|
||||||
|
padding: $dropdown-item-padding-y $dropdown-item-padding-x;
|
||||||
|
clear: both;
|
||||||
|
font-weight: $font-weight-normal;
|
||||||
|
color: $dropdown-link-color;
|
||||||
|
text-align: inherit; // For `<button>`s
|
||||||
|
text-decoration: if($link-decoration == none, null, none);
|
||||||
|
white-space: nowrap; // prevent links from randomly breaking onto new lines
|
||||||
|
background-color: transparent; // For `<button>`s
|
||||||
|
border: 0; // For `<button>`s
|
||||||
|
|
||||||
|
// Prevent dropdown overflow if there's no padding
|
||||||
|
// See https://github.com/twbs/bootstrap/pull/27703
|
||||||
|
@if $dropdown-padding-y == 0 {
|
||||||
|
&:first-child {
|
||||||
|
@include border-top-radius($dropdown-inner-border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
@include border-bottom-radius($dropdown-inner-border-radius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include hover-focus() {
|
||||||
|
color: $dropdown-link-hover-color;
|
||||||
|
text-decoration: none;
|
||||||
|
@include gradient-bg($dropdown-link-hover-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active,
|
||||||
|
&:active {
|
||||||
|
color: $dropdown-link-active-color;
|
||||||
|
text-decoration: none;
|
||||||
|
@include gradient-bg($dropdown-link-active-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disabled,
|
||||||
|
&:disabled {
|
||||||
|
color: $dropdown-link-disabled-color;
|
||||||
|
pointer-events: none;
|
||||||
|
background-color: transparent;
|
||||||
|
// Remove CSS gradients if they're enabled
|
||||||
|
@if $enable-gradients {
|
||||||
|
background-image: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu.show {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dropdown section headers
|
||||||
|
.dropdown-header {
|
||||||
|
display: block;
|
||||||
|
padding: $dropdown-header-padding;
|
||||||
|
margin-bottom: 0; // for use with heading elements
|
||||||
|
@include font-size($font-size-sm);
|
||||||
|
color: $dropdown-header-color;
|
||||||
|
white-space: nowrap; // as with > li > a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dropdown text
|
||||||
|
.dropdown-item-text {
|
||||||
|
display: block;
|
||||||
|
padding: $dropdown-item-padding-y $dropdown-item-padding-x;
|
||||||
|
color: $dropdown-link-color;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,347 @@
|
||||||
|
// stylelint-disable selector-no-qualifying-type
|
||||||
|
|
||||||
|
//
|
||||||
|
// Textual form controls
|
||||||
|
//
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: $input-height;
|
||||||
|
padding: $input-padding-y $input-padding-x;
|
||||||
|
font-family: $input-font-family;
|
||||||
|
@include font-size($input-font-size);
|
||||||
|
font-weight: $input-font-weight;
|
||||||
|
line-height: $input-line-height;
|
||||||
|
color: $input-color;
|
||||||
|
background-color: $input-bg;
|
||||||
|
background-clip: padding-box;
|
||||||
|
border: $input-border-width solid $input-border-color;
|
||||||
|
|
||||||
|
// Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.
|
||||||
|
@include border-radius($input-border-radius, 0);
|
||||||
|
|
||||||
|
@include box-shadow($input-box-shadow);
|
||||||
|
@include transition($input-transition);
|
||||||
|
|
||||||
|
// Unstyle the caret on `<select>`s in IE10+.
|
||||||
|
&::-ms-expand {
|
||||||
|
background-color: transparent;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove select outline from select box in FF
|
||||||
|
&:-moz-focusring {
|
||||||
|
color: transparent;
|
||||||
|
text-shadow: 0 0 0 $input-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Customize the `:focus` state to imitate native WebKit styles.
|
||||||
|
@include form-control-focus($ignore-warning: true);
|
||||||
|
|
||||||
|
// Placeholder
|
||||||
|
&::placeholder {
|
||||||
|
color: $input-placeholder-color;
|
||||||
|
// Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disabled and read-only inputs
|
||||||
|
//
|
||||||
|
// HTML5 says that controls under a fieldset > legend:first-child won't be
|
||||||
|
// disabled if the fieldset is disabled. Due to implementation difficulty, we
|
||||||
|
// don't honor that edge case; we style them as disabled anyway.
|
||||||
|
&:disabled,
|
||||||
|
&[readonly] {
|
||||||
|
background-color: $input-disabled-bg;
|
||||||
|
// iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="date"],
|
||||||
|
input[type="time"],
|
||||||
|
input[type="datetime-local"],
|
||||||
|
input[type="month"] {
|
||||||
|
&.form-control {
|
||||||
|
appearance: none; // Fix appearance for date inputs in Safari
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
select.form-control {
|
||||||
|
&:focus::-ms-value {
|
||||||
|
// Suppress the nested default white text on blue background highlight given to
|
||||||
|
// the selected option text when the (still closed) <select> receives focus
|
||||||
|
// in IE and (under certain conditions) Edge, as it looks bad and cannot be made to
|
||||||
|
// match the appearance of the native widget.
|
||||||
|
// See https://github.com/twbs/bootstrap/issues/19398.
|
||||||
|
color: $input-color;
|
||||||
|
background-color: $input-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make file inputs better match text inputs by forcing them to new lines.
|
||||||
|
.form-control-file,
|
||||||
|
.form-control-range {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Labels
|
||||||
|
//
|
||||||
|
|
||||||
|
// For use with horizontal and inline forms, when you need the label (or legend)
|
||||||
|
// text to align with the form controls.
|
||||||
|
.col-form-label {
|
||||||
|
padding-top: add($input-padding-y, $input-border-width);
|
||||||
|
padding-bottom: add($input-padding-y, $input-border-width);
|
||||||
|
margin-bottom: 0; // Override the `<label>/<legend>` default
|
||||||
|
@include font-size(inherit); // Override the `<legend>` default
|
||||||
|
line-height: $input-line-height;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-form-label-lg {
|
||||||
|
padding-top: add($input-padding-y-lg, $input-border-width);
|
||||||
|
padding-bottom: add($input-padding-y-lg, $input-border-width);
|
||||||
|
@include font-size($input-font-size-lg);
|
||||||
|
line-height: $input-line-height-lg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-form-label-sm {
|
||||||
|
padding-top: add($input-padding-y-sm, $input-border-width);
|
||||||
|
padding-bottom: add($input-padding-y-sm, $input-border-width);
|
||||||
|
@include font-size($input-font-size-sm);
|
||||||
|
line-height: $input-line-height-sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Readonly controls as plain text
|
||||||
|
//
|
||||||
|
// Apply class to a readonly input to make it appear like regular plain
|
||||||
|
// text (without any border, background color, focus indicator)
|
||||||
|
|
||||||
|
.form-control-plaintext {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
padding: $input-padding-y 0;
|
||||||
|
margin-bottom: 0; // match inputs if this class comes on inputs with default margins
|
||||||
|
@include font-size($input-font-size);
|
||||||
|
line-height: $input-line-height;
|
||||||
|
color: $input-plaintext-color;
|
||||||
|
background-color: transparent;
|
||||||
|
border: solid transparent;
|
||||||
|
border-width: $input-border-width 0;
|
||||||
|
|
||||||
|
&.form-control-sm,
|
||||||
|
&.form-control-lg {
|
||||||
|
padding-right: 0;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Form control sizing
|
||||||
|
//
|
||||||
|
// Build on `.form-control` with modifier classes to decrease or increase the
|
||||||
|
// height and font-size of form controls.
|
||||||
|
//
|
||||||
|
// Repeated in `_input_group.scss` to avoid Sass extend issues.
|
||||||
|
|
||||||
|
.form-control-sm {
|
||||||
|
height: $input-height-sm;
|
||||||
|
padding: $input-padding-y-sm $input-padding-x-sm;
|
||||||
|
@include font-size($input-font-size-sm);
|
||||||
|
line-height: $input-line-height-sm;
|
||||||
|
@include border-radius($input-border-radius-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control-lg {
|
||||||
|
height: $input-height-lg;
|
||||||
|
padding: $input-padding-y-lg $input-padding-x-lg;
|
||||||
|
@include font-size($input-font-size-lg);
|
||||||
|
line-height: $input-line-height-lg;
|
||||||
|
@include border-radius($input-border-radius-lg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// stylelint-disable-next-line no-duplicate-selectors
|
||||||
|
select.form-control {
|
||||||
|
&[size],
|
||||||
|
&[multiple] {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea.form-control {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Form groups
|
||||||
|
//
|
||||||
|
// Designed to help with the organization and spacing of vertical forms. For
|
||||||
|
// horizontal forms, use the predefined grid classes.
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: $form-group-margin-bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-text {
|
||||||
|
display: block;
|
||||||
|
margin-top: $form-text-margin-top;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Form grid
|
||||||
|
//
|
||||||
|
// Special replacement for our grid system's `.row` for tighter form layouts.
|
||||||
|
|
||||||
|
.form-row {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-right: -$form-grid-gutter-width / 2;
|
||||||
|
margin-left: -$form-grid-gutter-width / 2;
|
||||||
|
|
||||||
|
> .col,
|
||||||
|
> [class*="col-"] {
|
||||||
|
padding-right: $form-grid-gutter-width / 2;
|
||||||
|
padding-left: $form-grid-gutter-width / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Checkboxes and radios
|
||||||
|
//
|
||||||
|
// Indent the labels to position radios/checkboxes as hanging controls.
|
||||||
|
|
||||||
|
.form-check {
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
padding-left: $form-check-input-gutter;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-check-input {
|
||||||
|
position: absolute;
|
||||||
|
margin-top: $form-check-input-margin-y;
|
||||||
|
margin-left: -$form-check-input-gutter;
|
||||||
|
|
||||||
|
// Use [disabled] and :disabled for workaround https://github.com/twbs/bootstrap/issues/28247
|
||||||
|
&[disabled] ~ .form-check-label,
|
||||||
|
&:disabled ~ .form-check-label {
|
||||||
|
color: $text-muted;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-check-label {
|
||||||
|
margin-bottom: 0; // Override default `<label>` bottom margin
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-check-inline {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
padding-left: 0; // Override base .form-check
|
||||||
|
margin-right: $form-check-inline-margin-x;
|
||||||
|
|
||||||
|
// Undo .form-check-input defaults and add some `margin-right`.
|
||||||
|
.form-check-input {
|
||||||
|
position: static;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-right: $form-check-inline-input-margin-x;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Form validation
|
||||||
|
//
|
||||||
|
// Provide feedback to users when form field values are valid or invalid. Works
|
||||||
|
// primarily for client-side validation via scoped `:invalid` and `:valid`
|
||||||
|
// pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for
|
||||||
|
// server side validation.
|
||||||
|
|
||||||
|
@each $state, $data in $form-validation-states {
|
||||||
|
@include form-validation-state($state, map-get($data, color), map-get($data, icon));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inline forms
|
||||||
|
//
|
||||||
|
// Make forms appear inline(-block) by adding the `.form-inline` class. Inline
|
||||||
|
// forms begin stacked on extra small (mobile) devices and then go inline when
|
||||||
|
// viewports reach <768px.
|
||||||
|
//
|
||||||
|
// Requires wrapping inputs and labels with `.form-group` for proper display of
|
||||||
|
// default HTML form controls and our custom form controls (e.g., input groups).
|
||||||
|
|
||||||
|
.form-inline {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row wrap;
|
||||||
|
align-items: center; // Prevent shorter elements from growing to same height as others (e.g., small buttons growing to normal sized button height)
|
||||||
|
|
||||||
|
// Because we use flex, the initial sizing of checkboxes is collapsed and
|
||||||
|
// doesn't occupy the full-width (which is what we want for xs grid tier),
|
||||||
|
// so we force that here.
|
||||||
|
.form-check {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kick in the inline
|
||||||
|
@include media-breakpoint-up(sm) {
|
||||||
|
label {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inline-block all the things for "inline"
|
||||||
|
.form-group {
|
||||||
|
display: flex;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
flex-flow: row wrap;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow folks to *not* use `.form-group`
|
||||||
|
.form-control {
|
||||||
|
display: inline-block;
|
||||||
|
width: auto; // Prevent labels from stacking above inputs in `.form-group`
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make static controls behave like regular ones
|
||||||
|
.form-control-plaintext {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group,
|
||||||
|
.custom-select {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove default margin on radios/checkboxes that were used for stacking, and
|
||||||
|
// then undo the floating of radios and checkboxes to match.
|
||||||
|
.form-check {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: auto;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
.form-check-input {
|
||||||
|
position: relative;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-right: $form-check-input-margin-x;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-control {
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.custom-control-label {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,141 @@
|
||||||
|
// Bootstrap functions
|
||||||
|
//
|
||||||
|
// Utility mixins and functions for evaluating source code across our variables, maps, and mixins.
|
||||||
|
|
||||||
|
// Ascending
|
||||||
|
// Used to evaluate Sass maps like our grid breakpoints.
|
||||||
|
@mixin _assert-ascending($map, $map-name) {
|
||||||
|
$prev-key: null;
|
||||||
|
$prev-num: null;
|
||||||
|
@each $key, $num in $map {
|
||||||
|
@if $prev-num == null or unit($num) == "%" or unit($prev-num) == "%" {
|
||||||
|
// Do nothing
|
||||||
|
} @else if not comparable($prev-num, $num) {
|
||||||
|
@warn "Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !";
|
||||||
|
} @else if $prev-num >= $num {
|
||||||
|
@warn "Invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} which isn't greater than #{$prev-num}, the value of the previous key '#{$prev-key}' !";
|
||||||
|
}
|
||||||
|
$prev-key: $key;
|
||||||
|
$prev-num: $num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Starts at zero
|
||||||
|
// Used to ensure the min-width of the lowest breakpoint starts at 0.
|
||||||
|
@mixin _assert-starts-at-zero($map, $map-name: "$grid-breakpoints") {
|
||||||
|
@if length($map) > 0 {
|
||||||
|
$values: map-values($map);
|
||||||
|
$first-value: nth($values, 1);
|
||||||
|
@if $first-value != 0 {
|
||||||
|
@warn "First breakpoint in #{$map-name} must start at 0, but starts at #{$first-value}.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace `$search` with `$replace` in `$string`
|
||||||
|
// Used on our SVG icon backgrounds for custom forms.
|
||||||
|
//
|
||||||
|
// @author Hugo Giraudel
|
||||||
|
// @param {String} $string - Initial string
|
||||||
|
// @param {String} $search - Substring to replace
|
||||||
|
// @param {String} $replace ('') - New value
|
||||||
|
// @return {String} - Updated string
|
||||||
|
@function str-replace($string, $search, $replace: "") {
|
||||||
|
$index: str-index($string, $search);
|
||||||
|
|
||||||
|
@if $index {
|
||||||
|
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
|
||||||
|
}
|
||||||
|
|
||||||
|
@return $string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// See https://codepen.io/kevinweber/pen/dXWoRw
|
||||||
|
@function escape-svg($string) {
|
||||||
|
@if str-index($string, "data:image/svg+xml") {
|
||||||
|
@each $char, $encoded in $escaped-characters {
|
||||||
|
// Do not escape the url brackets
|
||||||
|
@if str-index($string, "url(") == 1 {
|
||||||
|
$string: url("#{str-replace(str-slice($string, 6, -3), $char, $encoded)}");
|
||||||
|
} @else {
|
||||||
|
$string: str-replace($string, $char, $encoded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@return $string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Color contrast
|
||||||
|
@function color-yiq($color, $dark: $yiq-text-dark, $light: $yiq-text-light) {
|
||||||
|
$r: red($color);
|
||||||
|
$g: green($color);
|
||||||
|
$b: blue($color);
|
||||||
|
|
||||||
|
$yiq: (($r * 299) + ($g * 587) + ($b * 114)) / 1000;
|
||||||
|
|
||||||
|
@if ($yiq >= $yiq-contrasted-threshold) {
|
||||||
|
@return $dark;
|
||||||
|
} @else {
|
||||||
|
@return $light;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve color Sass maps
|
||||||
|
@function color($key: "blue") {
|
||||||
|
@return map-get($colors, $key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@function theme-color($key: "primary") {
|
||||||
|
@return map-get($theme-colors, $key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@function gray($key: "100") {
|
||||||
|
@return map-get($grays, $key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request a theme color level
|
||||||
|
@function theme-color-level($color-name: "primary", $level: 0) {
|
||||||
|
$color: theme-color($color-name);
|
||||||
|
$color-base: if($level > 0, $black, $white);
|
||||||
|
$level: abs($level);
|
||||||
|
|
||||||
|
@return mix($color-base, $color, $level * $theme-color-interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return valid calc
|
||||||
|
@function add($value1, $value2, $return-calc: true) {
|
||||||
|
@if $value1 == null {
|
||||||
|
@return $value2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $value2 == null {
|
||||||
|
@return $value1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {
|
||||||
|
@return $value1 + $value2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@return if($return-calc == true, calc(#{$value1} + #{$value2}), $value1 + unquote(" + ") + $value2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@function subtract($value1, $value2, $return-calc: true) {
|
||||||
|
@if $value1 == null and $value2 == null {
|
||||||
|
@return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $value1 == null {
|
||||||
|
@return -$value2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $value2 == null {
|
||||||
|
@return $value1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {
|
||||||
|
@return $value1 - $value2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@return if($return-calc == true, calc(#{$value1} - #{$value2}), $value1 + unquote(" - ") + $value2);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
// Container widths
|
||||||
|
//
|
||||||
|
// Set the container width, and override it for fixed navbars in media queries.
|
||||||
|
|
||||||
|
@if $enable-grid-classes {
|
||||||
|
// Single container class with breakpoint max-widths
|
||||||
|
.container {
|
||||||
|
@include make-container();
|
||||||
|
@include make-container-max-widths();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 100% wide container at all breakpoints
|
||||||
|
.container-fluid {
|
||||||
|
@include make-container();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Responsive containers that are 100% wide until a breakpoint
|
||||||
|
@each $breakpoint, $container-max-width in $container-max-widths {
|
||||||
|
.container-#{$breakpoint} {
|
||||||
|
@extend .container-fluid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-breakpoint-up($breakpoint, $grid-breakpoints) {
|
||||||
|
%responsive-container-#{$breakpoint} {
|
||||||
|
max-width: $container-max-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extend each breakpoint which is smaller or equal to the current breakpoint
|
||||||
|
$extend-breakpoint: true;
|
||||||
|
|
||||||
|
@each $name, $width in $grid-breakpoints {
|
||||||
|
@if ($extend-breakpoint) {
|
||||||
|
.container#{breakpoint-infix($name, $grid-breakpoints)} {
|
||||||
|
@extend %responsive-container-#{$breakpoint};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Once the current breakpoint is reached, stop extending
|
||||||
|
@if ($breakpoint == $name) {
|
||||||
|
$extend-breakpoint: false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Row
|
||||||
|
//
|
||||||
|
// Rows contain your columns.
|
||||||
|
|
||||||
|
@if $enable-grid-classes {
|
||||||
|
.row {
|
||||||
|
@include make-row();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the negative margin from default .row, then the horizontal padding
|
||||||
|
// from all immediate children columns (to prevent runaway style inheritance).
|
||||||
|
.no-gutters {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 0;
|
||||||
|
|
||||||
|
> .col,
|
||||||
|
> [class*="col-"] {
|
||||||
|
padding-right: 0;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Columns
|
||||||
|
//
|
||||||
|
// Common styles for small and large grid columns
|
||||||
|
|
||||||
|
@if $enable-grid-classes {
|
||||||
|
@include make-grid-columns();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
// Responsive images (ensure images don't scale beyond their parents)
|
||||||
|
//
|
||||||
|
// This is purposefully opt-in via an explicit class rather than being the default for all `<img>`s.
|
||||||
|
// We previously tried the "images are responsive by default" approach in Bootstrap v2,
|
||||||
|
// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)
|
||||||
|
// which weren't expecting the images within themselves to be involuntarily resized.
|
||||||
|
// See also https://github.com/twbs/bootstrap/issues/18178
|
||||||
|
.img-fluid {
|
||||||
|
@include img-fluid();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Image thumbnails
|
||||||
|
.img-thumbnail {
|
||||||
|
padding: $thumbnail-padding;
|
||||||
|
background-color: $thumbnail-bg;
|
||||||
|
border: $thumbnail-border-width solid $thumbnail-border-color;
|
||||||
|
@include border-radius($thumbnail-border-radius);
|
||||||
|
@include box-shadow($thumbnail-box-shadow);
|
||||||
|
|
||||||
|
// Keep them at most 100% wide
|
||||||
|
@include img-fluid();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Figures
|
||||||
|
//
|
||||||
|
|
||||||
|
.figure {
|
||||||
|
// Ensures the caption's text aligns with the image.
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.figure-img {
|
||||||
|
margin-bottom: $spacer / 2;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.figure-caption {
|
||||||
|
@include font-size($figure-caption-font-size);
|
||||||
|
color: $figure-caption-color;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,192 @@
|
||||||
|
// stylelint-disable selector-no-qualifying-type
|
||||||
|
|
||||||
|
//
|
||||||
|
// Base styles
|
||||||
|
//
|
||||||
|
|
||||||
|
.input-group {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap; // For form validation feedback
|
||||||
|
align-items: stretch;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
> .form-control,
|
||||||
|
> .form-control-plaintext,
|
||||||
|
> .custom-select,
|
||||||
|
> .custom-file {
|
||||||
|
position: relative; // For focus state's z-index
|
||||||
|
flex: 1 1 auto;
|
||||||
|
width: 1%;
|
||||||
|
min-width: 0; // https://stackoverflow.com/questions/36247140/why-dont-flex-items-shrink-past-content-size
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
+ .form-control,
|
||||||
|
+ .custom-select,
|
||||||
|
+ .custom-file {
|
||||||
|
margin-left: -$input-border-width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bring the "active" form control to the top of surrounding elements
|
||||||
|
> .form-control:focus,
|
||||||
|
> .custom-select:focus,
|
||||||
|
> .custom-file .custom-file-input:focus ~ .custom-file-label {
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bring the custom file input above the label
|
||||||
|
> .custom-file .custom-file-input:focus {
|
||||||
|
z-index: 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .form-control,
|
||||||
|
> .custom-select {
|
||||||
|
&:not(:last-child) { @include border-right-radius(0); }
|
||||||
|
&:not(:first-child) { @include border-left-radius(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom file inputs have more complex markup, thus requiring different
|
||||||
|
// border-radius overrides.
|
||||||
|
> .custom-file {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&:not(:last-child) .custom-file-label,
|
||||||
|
&:not(:last-child) .custom-file-label::after { @include border-right-radius(0); }
|
||||||
|
&:not(:first-child) .custom-file-label { @include border-left-radius(0); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Prepend and append
|
||||||
|
//
|
||||||
|
// While it requires one extra layer of HTML for each, dedicated prepend and
|
||||||
|
// append elements allow us to 1) be less clever, 2) simplify our selectors, and
|
||||||
|
// 3) support HTML5 form validation.
|
||||||
|
|
||||||
|
.input-group-prepend,
|
||||||
|
.input-group-append {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
// Ensure buttons are always above inputs for more visually pleasing borders.
|
||||||
|
// This isn't needed for `.input-group-text` since it shares the same border-color
|
||||||
|
// as our inputs.
|
||||||
|
.btn {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn + .btn,
|
||||||
|
.btn + .input-group-text,
|
||||||
|
.input-group-text + .input-group-text,
|
||||||
|
.input-group-text + .btn {
|
||||||
|
margin-left: -$input-border-width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group-prepend { margin-right: -$input-border-width; }
|
||||||
|
.input-group-append { margin-left: -$input-border-width; }
|
||||||
|
|
||||||
|
|
||||||
|
// Textual addons
|
||||||
|
//
|
||||||
|
// Serves as a catch-all element for any text or radio/checkbox input you wish
|
||||||
|
// to prepend or append to an input.
|
||||||
|
|
||||||
|
.input-group-text {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: $input-padding-y $input-padding-x;
|
||||||
|
margin-bottom: 0; // Allow use of <label> elements by overriding our default margin-bottom
|
||||||
|
@include font-size($input-font-size); // Match inputs
|
||||||
|
font-weight: $font-weight-normal;
|
||||||
|
line-height: $input-line-height;
|
||||||
|
color: $input-group-addon-color;
|
||||||
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
background-color: $input-group-addon-bg;
|
||||||
|
border: $input-border-width solid $input-group-addon-border-color;
|
||||||
|
@include border-radius($input-border-radius);
|
||||||
|
|
||||||
|
// Nuke default margins from checkboxes and radios to vertically center within.
|
||||||
|
input[type="radio"],
|
||||||
|
input[type="checkbox"] {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Sizing
|
||||||
|
//
|
||||||
|
// Remix the default form control sizing classes into new ones for easier
|
||||||
|
// manipulation.
|
||||||
|
|
||||||
|
.input-group-lg > .form-control:not(textarea),
|
||||||
|
.input-group-lg > .custom-select {
|
||||||
|
height: $input-height-lg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group-lg > .form-control,
|
||||||
|
.input-group-lg > .custom-select,
|
||||||
|
.input-group-lg > .input-group-prepend > .input-group-text,
|
||||||
|
.input-group-lg > .input-group-append > .input-group-text,
|
||||||
|
.input-group-lg > .input-group-prepend > .btn,
|
||||||
|
.input-group-lg > .input-group-append > .btn {
|
||||||
|
padding: $input-padding-y-lg $input-padding-x-lg;
|
||||||
|
@include font-size($input-font-size-lg);
|
||||||
|
line-height: $input-line-height-lg;
|
||||||
|
@include border-radius($input-border-radius-lg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group-sm > .form-control:not(textarea),
|
||||||
|
.input-group-sm > .custom-select {
|
||||||
|
height: $input-height-sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group-sm > .form-control,
|
||||||
|
.input-group-sm > .custom-select,
|
||||||
|
.input-group-sm > .input-group-prepend > .input-group-text,
|
||||||
|
.input-group-sm > .input-group-append > .input-group-text,
|
||||||
|
.input-group-sm > .input-group-prepend > .btn,
|
||||||
|
.input-group-sm > .input-group-append > .btn {
|
||||||
|
padding: $input-padding-y-sm $input-padding-x-sm;
|
||||||
|
@include font-size($input-font-size-sm);
|
||||||
|
line-height: $input-line-height-sm;
|
||||||
|
@include border-radius($input-border-radius-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group-lg > .custom-select,
|
||||||
|
.input-group-sm > .custom-select {
|
||||||
|
padding-right: $custom-select-padding-x + $custom-select-indicator-padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Prepend and append rounded corners
|
||||||
|
//
|
||||||
|
// These rulesets must come after the sizing ones to properly override sm and lg
|
||||||
|
// border-radius values when extending. They're more specific than we'd like
|
||||||
|
// with the `.input-group >` part, but without it, we cannot override the sizing.
|
||||||
|
|
||||||
|
|
||||||
|
.input-group > .input-group-prepend > .btn,
|
||||||
|
.input-group > .input-group-prepend > .input-group-text,
|
||||||
|
.input-group > .input-group-append:not(:last-child) > .btn,
|
||||||
|
.input-group > .input-group-append:not(:last-child) > .input-group-text,
|
||||||
|
.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),
|
||||||
|
.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {
|
||||||
|
@include border-right-radius(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group > .input-group-append > .btn,
|
||||||
|
.input-group > .input-group-append > .input-group-text,
|
||||||
|
.input-group > .input-group-prepend:not(:first-child) > .btn,
|
||||||
|
.input-group > .input-group-prepend:not(:first-child) > .input-group-text,
|
||||||
|
.input-group > .input-group-prepend:first-child > .btn:not(:first-child),
|
||||||
|
.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {
|
||||||
|
@include border-left-radius(0);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
.jumbotron {
|
||||||
|
padding: $jumbotron-padding ($jumbotron-padding / 2);
|
||||||
|
margin-bottom: $jumbotron-padding;
|
||||||
|
color: $jumbotron-color;
|
||||||
|
background-color: $jumbotron-bg;
|
||||||
|
@include border-radius($border-radius-lg);
|
||||||
|
|
||||||
|
@include media-breakpoint-up(sm) {
|
||||||
|
padding: ($jumbotron-padding * 2) $jumbotron-padding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.jumbotron-fluid {
|
||||||
|
padding-right: 0;
|
||||||
|
padding-left: 0;
|
||||||
|
@include border-radius(0);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,154 @@
|
||||||
|
// Base class
|
||||||
|
//
|
||||||
|
// Easily usable on <ul>, <ol>, or <div>.
|
||||||
|
|
||||||
|
.list-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
// No need to set list-style: none; since .list-group-item is block level
|
||||||
|
padding-left: 0; // reset padding because ul and ol
|
||||||
|
margin-bottom: 0;
|
||||||
|
@include border-radius($list-group-border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Interactive list items
|
||||||
|
//
|
||||||
|
// Use anchor or button elements instead of `li`s or `div`s to create interactive
|
||||||
|
// list items. Includes an extra `.active` modifier class for selected items.
|
||||||
|
|
||||||
|
.list-group-item-action {
|
||||||
|
width: 100%; // For `<button>`s (anchors become 100% by default though)
|
||||||
|
color: $list-group-action-color;
|
||||||
|
text-align: inherit; // For `<button>`s (anchors inherit)
|
||||||
|
|
||||||
|
// Hover state
|
||||||
|
@include hover-focus() {
|
||||||
|
z-index: 1; // Place hover/focus items above their siblings for proper border styling
|
||||||
|
color: $list-group-action-hover-color;
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: $list-group-hover-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
color: $list-group-action-active-color;
|
||||||
|
background-color: $list-group-action-active-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Individual list items
|
||||||
|
//
|
||||||
|
// Use on `li`s or `div`s within the `.list-group` parent.
|
||||||
|
|
||||||
|
.list-group-item {
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
padding: $list-group-item-padding-y $list-group-item-padding-x;
|
||||||
|
color: $list-group-color;
|
||||||
|
text-decoration: if($link-decoration == none, null, none);
|
||||||
|
background-color: $list-group-bg;
|
||||||
|
border: $list-group-border-width solid $list-group-border-color;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
@include border-top-radius(inherit);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
@include border-bottom-radius(inherit);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disabled,
|
||||||
|
&:disabled {
|
||||||
|
color: $list-group-disabled-color;
|
||||||
|
pointer-events: none;
|
||||||
|
background-color: $list-group-disabled-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Include both here for `<a>`s and `<button>`s
|
||||||
|
&.active {
|
||||||
|
z-index: 2; // Place active items above their siblings for proper border styling
|
||||||
|
color: $list-group-active-color;
|
||||||
|
background-color: $list-group-active-bg;
|
||||||
|
border-color: $list-group-active-border-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
& + & {
|
||||||
|
border-top-width: 0;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
margin-top: -$list-group-border-width;
|
||||||
|
border-top-width: $list-group-border-width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Horizontal
|
||||||
|
//
|
||||||
|
// Change the layout of list group items from vertical (default) to horizontal.
|
||||||
|
|
||||||
|
@each $breakpoint in map-keys($grid-breakpoints) {
|
||||||
|
@include media-breakpoint-up($breakpoint) {
|
||||||
|
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
|
||||||
|
|
||||||
|
.list-group-horizontal#{$infix} {
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
> .list-group-item {
|
||||||
|
&:first-child {
|
||||||
|
@include border-bottom-left-radius($list-group-border-radius);
|
||||||
|
@include border-top-right-radius(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
@include border-top-right-radius($list-group-border-radius);
|
||||||
|
@include border-bottom-left-radius(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
& + .list-group-item {
|
||||||
|
border-top-width: $list-group-border-width;
|
||||||
|
border-left-width: 0;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
margin-left: -$list-group-border-width;
|
||||||
|
border-left-width: $list-group-border-width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Flush list items
|
||||||
|
//
|
||||||
|
// Remove borders and border-radius to keep list group items edge-to-edge. Most
|
||||||
|
// useful within other components (e.g., cards).
|
||||||
|
|
||||||
|
.list-group-flush {
|
||||||
|
@include border-radius(0);
|
||||||
|
|
||||||
|
> .list-group-item {
|
||||||
|
border-width: 0 0 $list-group-border-width;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom-width: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Contextual variants
|
||||||
|
//
|
||||||
|
// Add modifier classes to change text and background color on individual items.
|
||||||
|
// Organizationally, this must come after the `:hover` states.
|
||||||
|
|
||||||
|
@each $color, $value in $theme-colors {
|
||||||
|
@include list-group-item-variant($color, theme-color-level($color, -9), theme-color-level($color, 6));
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
.media {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-body {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
// Toggles
|
||||||
|
//
|
||||||
|
// Used in conjunction with global variables to enable certain theme features.
|
||||||
|
|
||||||
|
// Vendor
|
||||||
|
@import "vendor/rfs";
|
||||||
|
|
||||||
|
// Deprecate
|
||||||
|
@import "mixins/deprecate";
|
||||||
|
|
||||||
|
// Utilities
|
||||||
|
@import "mixins/breakpoints";
|
||||||
|
@import "mixins/hover";
|
||||||
|
@import "mixins/image";
|
||||||
|
@import "mixins/badge";
|
||||||
|
@import "mixins/resize";
|
||||||
|
@import "mixins/screen-reader";
|
||||||
|
@import "mixins/size";
|
||||||
|
@import "mixins/reset-text";
|
||||||
|
@import "mixins/text-emphasis";
|
||||||
|
@import "mixins/text-hide";
|
||||||
|
@import "mixins/text-truncate";
|
||||||
|
@import "mixins/visibility";
|
||||||
|
|
||||||
|
// Components
|
||||||
|
@import "mixins/alert";
|
||||||
|
@import "mixins/buttons";
|
||||||
|
@import "mixins/caret";
|
||||||
|
@import "mixins/pagination";
|
||||||
|
@import "mixins/lists";
|
||||||
|
@import "mixins/list-group";
|
||||||
|
@import "mixins/nav-divider";
|
||||||
|
@import "mixins/forms";
|
||||||
|
@import "mixins/table-row";
|
||||||
|
|
||||||
|
// Skins
|
||||||
|
@import "mixins/background-variant";
|
||||||
|
@import "mixins/border-radius";
|
||||||
|
@import "mixins/box-shadow";
|
||||||
|
@import "mixins/gradients";
|
||||||
|
@import "mixins/transition";
|
||||||
|
|
||||||
|
// Layout
|
||||||
|
@import "mixins/clearfix";
|
||||||
|
@import "mixins/grid-framework";
|
||||||
|
@import "mixins/grid";
|
||||||
|
@import "mixins/float";
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue