first commit

This commit is contained in:
arief 2024-06-12 11:40:43 +07:00
parent 3d6e640525
commit 939a90b84d
2003 changed files with 197204 additions and 0 deletions

1
.ftpquota Normal file
View File

@ -0,0 +1 @@
26 858880

146
UsersLog.php Normal file
View File

@ -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>

86
WebAbsen.php Normal file
View File

@ -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.";
}
}
?>

243
absensi/RFID/RFID.ino Normal file
View 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)
;
}
}

69
absensi/RFID/icon.h Normal file
View File

@ -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
};

View File

@ -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);
?>

13
absensi/apps/config.php Normal file
View File

@ -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);
}
?>

80
absensi/apps/data.php Normal file
View File

@ -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>

View File

@ -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 &copy; 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>

View File

@ -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);
?>

View File

@ -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"> &nbsp
<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 &copy; 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>

View File

@ -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"> &nbsp
<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 &copy; 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>

View File

@ -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();
}
}
?>

View File

@ -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"> &nbsp
<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 &copy; 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>

View File

@ -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> &nbsp";
echo "<a href='data_invalid-delete.php?id=". $row['id'] ."' title='Hapus' data-toggle='tooltip'><span class='fa fa-trash'></span></a> &nbsp";
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 &copy; 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>

View File

@ -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"> &nbsp
<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 &copy; 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>

View File

@ -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();
}
}
?>

View File

@ -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"> &nbsp
<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 &copy; 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>

View File

@ -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> &nbsp";
echo "<a href='data_karyawan-update.php?id=". $row['id'] ."' title='Edit' data-toggle='tooltip'><span class='fa fa-edit'></span></a> &nbsp;";
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 &copy; 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>

View File

@ -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 &copy; 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>

View File

@ -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"> &nbsp
<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 &copy; 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>

View File

@ -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"> &nbsp
<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 &copy; 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>

View File

@ -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();
}
}
?>

View File

@ -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"> &nbsp
<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 &copy; 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>

View File

@ -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 &copy; 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>

113
absensi/apps/error.php Normal file
View File

@ -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">&larr; 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 &copy; 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>

29
absensi/apps/excel.php Normal file
View File

@ -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>

122
absensi/apps/export.php Normal file
View File

@ -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();
}
?>

392
absensi/apps/index.php Normal file
View File

@ -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 &rarr;</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 &copy; 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
absensi/apps/logout.php Normal file
View File

View File

@ -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>

View File

@ -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>

View File

@ -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);
}
?>

BIN
absensi/database sql.rar Normal file

Binary file not shown.

View File

@ -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.

6
absensi/index.php Normal file
View File

@ -0,0 +1,6 @@
<?php
header('Location: apps'); /* Redirect browser */
/* Make sure that code below does not get executed when we redirect. */
exit;
?>

BIN
absensi/src.rar Normal file

Binary file not shown.

11223
absensi/src/css/sb-admin-2.css Normal file

File diff suppressed because it is too large Load Diff

10
absensi/src/css/sb-admin-2.min.css vendored Normal file

File diff suppressed because one or more lines are too long

BIN
absensi/src/img/Sinta.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
absensi/src/img/arif.jpg Normal file

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

View File

@ -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);
}
}
}
}
});

View File

@ -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);
}
}
},
}
});

View File

@ -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,
},
});

View File

@ -0,0 +1,4 @@
// Call the dataTables jQuery plugin
$(document).ready(function() {
$('#dataTable').DataTable();
});

View File

@ -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

7
absensi/src/js/sb-admin-2.min.js vendored Normal file
View File

@ -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);

View File

@ -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;
}
}
}

View File

@ -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';
}
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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%;
}
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,3 @@
@import "navs/global.scss";
@import "navs/topbar.scss";
@import "navs/sidebar.scss";

View File

@ -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";

View File

@ -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;

View File

@ -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;
}
}
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}
}
}
}

View File

@ -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";

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -0,0 +1,7 @@
@each $color, $value in $theme-colors {
@each $position in ['left', 'bottom'] {
.border-#{$position}-#{$color} {
border-#{$position}: .25rem solid $value !important;
}
}
}

View File

@ -0,0 +1,4 @@
// Overflow Hidden
.o-hidden {
overflow: hidden !important;
}

View File

@ -0,0 +1,3 @@
.progress-sm {
height: .5rem;
}

View File

@ -0,0 +1,7 @@
.rotate-15 {
transform: rotate(15deg);
}
.rotate-n-15 {
transform: rotate(-15deg);
}

View File

@ -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

View File

@ -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));
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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%;
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}
}
}

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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));
}

View File

@ -0,0 +1,8 @@
.media {
display: flex;
align-items: flex-start;
}
.media-body {
flex: 1;
}

View File

@ -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