@extends('layouts.admin') @section('title', setting('school_name', 'ShulePoint') . ' | Biometric Devices') @section('page-title', 'Biometric Devices') @section('content') {{-- Stat strip (same widgets as Dashboard) --}}
{{ number_format($devices->count()) }}Devices registered
{{ number_format($devices->where('is_active', true)->count()) }}Active devices
{{ number_format($devices->sum('today_logs_count')) }}Punches today
{{ number_format($unmatchedCount) }}Unmatched punches
@if(! $sdkInstalled)
Built-in ZKTeco driver active. It handles K40 Pro / F18 / iClock panels over TCP port 4370 out of the box. For wider firmware coverage you may optionally run composer require rats/zkteco — the system will use it automatically when present.
@else
rats/zkteco SDK detected — full firmware support enabled.
@endif
{{-- Add device form --}}

Add scanning device

@csrf

The device and this server must be on the same network. On the panel: Menu → Comm. → Ethernet, set a static IP, and keep port 4370 open. Saving tests the connection automatically.

Enrol fingerprints

On the device, enrol each learner/staff and note their User ID number.

Then enter that same number as the Biometric ID on the learner / staff record (admission or staff number also works as a fallback).

Unmatched punches appear below so you can enrol them and re-pull.

{{-- Device list --}}

Registered devices {{ $devices->count() }} total

@forelse($devices as $d) @empty @endforelse
DeviceNetworkUseLast syncStatusActions
{{ $d->name }} {{ $d->model ?? 'ZKTeco panel' }}@if($d->location) · {{ $d->location }}@endif {{ $d->logs_count }} punch(es) · {{ $d->today_logs_count }} today · {{ $d->unprocessed_logs_count }} unmatched {{ $d->ip_address }}:{{ $d->port }} {{ ucfirst($d->purpose) }} {{ $d->last_sync_at?->diffForHumans() ?? 'Never' }} @if($d->last_seen_at)seen {{ $d->last_seen_at->diffForHumans() }}@endif @if($d->is_active)Active @elseDisabled@endif
@csrf
@csrf

No devices yet

Add the first biometric scanner using the form.

{{-- Recent punches --}}

Latest punches (all devices)

@forelse($recentLogs as $l) @empty @endforelse
TimeEnrol IDDeviceMatched toState
{{ $l->punch_time->format('Y-m-d H:i') }} {{ $l->device_user_id }} {{ $l->device->name ?? '—' }} @if($l->learner){{ $l->learner->first_name }} {{ $l->learner->last_name }} @elseif($l->staff){{ $l->staff->first_name }} {{ $l->staff->last_name }} @elseUnmatched@endif {{ $l->punch_state == 1 ? 'Check-out' : 'Check-in' }}
No punches synced yet — open a device and choose Pull attendance.
{{-- Edit / delete modals --}} @foreach($devices as $d) @endforeach @endsection