package burst;
import java.awt.*;
import java.awt.event.*;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import javax.swing.*;
public class MarkAttendance extends JFrame {
private Connection con;
private JTextField idField;
private JTextArea logArea;
private JComboBox<String> roleComboBox;
public MarkAttendance() {
initDatabase();
initComponents();
setTitle("Attendance App");
setSize(2000, 1500);
setResizable(false);
setLocationRelativeTo(null);
setUndecorated(true);
try {
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Exception e) {
showError("Failed to apply UI theme", e);
}
loadAttendanceRecords();
setVisible(true);
}
private void initDatabase() {
String db_url = "jdbc:mysql://localhost/span";
String db_username = "root";
String db_password = "";
try {
con = DriverManager.getConnection(db_url, db_username, db_password);
} catch (SQLException e) {
showError("Database connection failed", e);
System.exit(1);
}
}
private void initComponents() {
idField = new JTextField();
logArea = new JTextArea();
logArea.setEditable(false);
logArea.setFont(new Font("Arial", Font.PLAIN, 14));
logArea.setBackground(new Color(255, 182, 193));
idField.setFont(new Font("Arial", Font.PLAIN, 18));
idField.setPreferredSize(new Dimension(200, 40));
idField.setBackground(new Color(135, 206, 250));
idField.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
handleKeyReleased();
}
});
setLayout(new BorderLayout(5, 5));
JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));
topPanel.add(new JLabel("Select Role: "));
String[] roles = {"All", "Student", "Trainer", "Staff"};
roleComboBox = new JComboBox<>(roles);
roleComboBox.setFont(new Font("Arial", Font.PLAIN, 16));
roleComboBox.addActionListener(e -> loadAttendanceRecords());
topPanel.add(roleComboBox);
topPanel.add(new JLabel("Enter ID: "));
topPanel.add(idField);
JLabel closeButton = new JLabel("X");
closeButton.setForeground(Color.RED);
closeButton.setFont(new Font("Times New Roman", Font.BOLD, 24));
closeButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
closeButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
dispose();
}
});
topPanel.add(closeButton);
JScrollPane scrollPane = new JScrollPane(logArea);
scrollPane.setBorder(BorderFactory.createTitledBorder("Attendance Log"));
add(topPanel, BorderLayout.NORTH);
add(scrollPane, BorderLayout.CENTER);
}
private void loadAttendanceRecords() {
String role = (String) roleComboBox.getSelectedItem();
logArea.setText("");
logArea.setFont(new Font("Courier New", Font.PLAIN, 18));
logArea.append("=============================================================
========================\n");
logArea.append(String.format("%-10s | %-20s | %-20s | %-10s | %-10s\n", "ID", "Name",
"Time", "Status", "Role"));
logArea.append("=============================================================
========================\n");
String query;
if ("All".equals(role)) {
query = """
SELECT a.id, s.name, a.date_time, a.status, 'Student' AS role
FROM stud_attendance a
JOIN students s ON a.id = s.id
WHERE DATE(a.date_time) = CURDATE()
UNION ALL
SELECT a.id, t.name, a.date_time, a.status, 'Trainer' AS role
FROM trainer_attendance a
JOIN trainers t ON a.id = t.id
WHERE DATE(a.date_time) = CURDATE()
UNION ALL
SELECT a.id, sf.name, a.date_time, a.status, 'Staff' AS role
FROM staff_attendance a
JOIN staff sf ON a.id = sf.id
WHERE DATE(a.date_time) = CURDATE()
ORDER BY a.date_time ASC;
""";
} else {
String tableName = getTableForRole(role);
String joinTable = getJoinTableForRole(role);
query = "SELECT a.id, t.name, a.date_time, a.status FROM " + tableName +
" a JOIN " + joinTable + " t ON a.id = t.id WHERE DATE(a.date_time) = CURDATE()
ORDER BY a.date_time ASC";
}
try (PreparedStatement stmt = con.prepareStatement(query);
ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
String id = rs.getString("id");
String name = rs.getString("name");
String dateTime = rs.getString("date_time");
String status = rs.getString("status");
String roleText = role.equals("All") ? rs.getString("role") : role;
logArea.append(String.format("%-10s | %-20s | %-20s | %-10s | %-10s\n", id, name,
dateTime, status, roleText));
logArea.append("-------------------------------------------------------------------------------------\n");
}
} catch (SQLException e) {
logArea.append("Error retrieving attendance: " + e.getMessage() + "\n");
}
}
private String getTableForRole(String role) {
return switch (role) {
case "Student" -> "stud_attendance";
case "Trainer" -> "trainer_attendance";
case "Staff" -> "staff_attendance";
default -> "";
};
}
private String getJoinTableForRole(String role) {
return switch (role) {
case "Student" -> "students";
case "Trainer" -> "trainers";
case "Staff" -> "staff";
default -> "";
};
}
private void handleKeyReleased() {
String id = idField.getText().trim();
String role = (String) roleComboBox.getSelectedItem();
if (isValidId(id, role)) {
markAttendance();
}
}
private boolean isValidId(String id, String role) {
return switch (role) {
case "Student" -> id.matches("^[A-Za-z]{3}/[A-Za-z]{2}/\\d{3}/\\d{2}$");
case "Trainer" -> id.matches("^TR-\\d{3}$");
case "Staff" -> id.matches("^ST-\\d{3}$");
default -> false;
};
}
private void markAttendance() {
String id = idField.getText().trim();
String role = (String) roleComboBox.getSelectedItem();
String tableName = getTableForRole(role);
String joinTable = getJoinTableForRole(role);
try {
String name = fetchNameForId(id, joinTable);
if (name == null) {
logArea.append("ID not found in the " + role + " database: " + id + "\n");
return;
}
if (hasAttendanceBeenRecordedToday(id, tableName)) {
logArea.append("Attendance already recorded for ID: " + id + "\n");
} else {
insertAttendanceRecord(id, name, tableName);
}
idField.setText("");
} catch (SQLException e) {
showError("Error marking attendance", e);
}
}
private String fetchNameForId(String id, String tableName) throws SQLException {
String query = "SELECT name FROM " + tableName + " WHERE id = ?";
try (PreparedStatement stmt = con.prepareStatement(query)) {
stmt.setString(1, id);
try (ResultSet rs = stmt.executeQuery()) {
if (rs.next()) {
return rs.getString("name");
}
}
}
return null;
}
private boolean hasAttendanceBeenRecordedToday(String id, String tableName) throws
SQLException {
String query = "SELECT * FROM " + tableName + " WHERE id = ? AND DATE(date_time) =
CURDATE()";
try (PreparedStatement stmt = con.prepareStatement(query)) {
stmt.setString(1, id);
return stmt.executeQuery().next();
}
}
private void insertAttendanceRecord(String id, String name, String tableName) throws
SQLException {
String query = "INSERT INTO " + tableName + " (id, name, date_time, status) VALUES (?, ?,
?, ?)";
try (PreparedStatement stmt = con.prepareStatement(query)) {
stmt.setString(1, id);
stmt.setString(2, name);
stmt.setString(3, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
stmt.setString(4, getStatusBasedOnTime(LocalDateTime.now()));
stmt.executeUpdate();
logArea.append("Attendance marked successfully for ID: " + id + " (Name: " + name +
")\n");
}
}
private String getStatusBasedOnTime(LocalDateTime now) {
return (now.getHour() > 8) ? "Late" : "Present";
}
private void showError(String message, Exception e) {
JOptionPane.showMessageDialog(this, message + ": " + e.getMessage(), "Error",
JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
}
}