mirror of
				https://github.com/StefBuwalda/cal_counter.git
				synced 2025-11-03 21:29:59 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			134 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
{% extends "base.html" %}
 | 
						|
 | 
						|
{% block content %}
 | 
						|
<div class="container py-5">
 | 
						|
    <!-- Header -->
 | 
						|
    <div class="text-center mb-4">
 | 
						|
        <h1 class="fw-bold">Barcode Scanner</h1>
 | 
						|
        <p class="text-muted">Use your camera to scan barcodes</p>
 | 
						|
    </div>
 | 
						|
 | 
						|
    <!-- Video preview -->
 | 
						|
    <div class="d-flex justify-content-center mb-4">
 | 
						|
        <video id="video" class="border rounded shadow-sm" style="width: 100%; max-width: 500px;" autoplay
 | 
						|
            muted></video>
 | 
						|
    </div>
 | 
						|
 | 
						|
    <!-- Start/Stop buttons -->
 | 
						|
    <div class="d-flex justify-content-center gap-3 mb-4">
 | 
						|
        <button id="startButton" class="btn btn-primary px-4">Start Scanning</button>
 | 
						|
        <button id="stopButton" class="btn btn-danger px-4">Stop</button>
 | 
						|
    </div>
 | 
						|
 | 
						|
    <!-- Search box and suggestions -->
 | 
						|
    <div class="d-flex justify-content-center mt-4">
 | 
						|
        <div class="w-100 position-relative" style="max-width: 500px;">
 | 
						|
            <!-- Input group (search + go button) -->
 | 
						|
            <div class="input-group">
 | 
						|
                <input type="text" id="search-box" class="form-control" placeholder="Search..." autocomplete="off">
 | 
						|
                <button id="go-button" class="btn btn-success">Go</button>
 | 
						|
            </div>
 | 
						|
 | 
						|
            <!-- Suggestions -->
 | 
						|
            <ul id="suggestions" class="list-group position-absolute w-100 mt-1" style="z-index: 1000;"></ul>
 | 
						|
        </div>
 | 
						|
    </div>
 | 
						|
 | 
						|
 | 
						|
    <!-- Suggestions list -->
 | 
						|
    <div class="d-flex justify-content-center">
 | 
						|
        <ul id="suggestions" class="list-group position-absolute mt-1 w-100" style="max-width: 500px; z-index: 1000;">
 | 
						|
        </ul>
 | 
						|
    </div>
 | 
						|
</div>
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
<script>
 | 
						|
    const searchBox = document.getElementById('search-box');
 | 
						|
    const suggestionsBox = document.getElementById('suggestions');
 | 
						|
    const goButton = document.getElementById('go-button');
 | 
						|
 | 
						|
    searchBox.addEventListener('input', function () {
 | 
						|
        const query = searchBox.value;
 | 
						|
        if (query.length < 2) {
 | 
						|
            suggestionsBox.innerHTML = '';
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        fetch(`{{url_for("add_meal.query")}}?q=${encodeURIComponent(query)}`)
 | 
						|
            .then(response => response.json())
 | 
						|
            .then(data => {
 | 
						|
                suggestionsBox.innerHTML = '';
 | 
						|
                data.forEach(item => {
 | 
						|
                    const li = document.createElement('li');
 | 
						|
                    li.textContent = item;
 | 
						|
 | 
						|
                    // Apply Bootstrap classes
 | 
						|
                    li.classList.add('list-group-item', 'list-group-item-action', 'cursor-pointer');
 | 
						|
 | 
						|
                    // Add click behavior
 | 
						|
                    li.addEventListener('click', () => {
 | 
						|
                        searchBox.value = item;
 | 
						|
                        suggestionsBox.innerHTML = '';
 | 
						|
                    });
 | 
						|
 | 
						|
                    // Add to suggestions box
 | 
						|
                    suggestionsBox.appendChild(li);
 | 
						|
                });
 | 
						|
            });
 | 
						|
    });
 | 
						|
 | 
						|
    // ✅ Redirect when the "Go" button is clicked
 | 
						|
    goButton.addEventListener('click', () => {
 | 
						|
        const value = searchBox.value.trim();
 | 
						|
        if (value) {
 | 
						|
            const baseURL = "{{url_for('add_meal.step3', input='!')}}";
 | 
						|
            window.location.href = baseURL.replace("!", encodeURIComponent(value));
 | 
						|
        }
 | 
						|
    });
 | 
						|
</script>
 | 
						|
 | 
						|
<script type="module">
 | 
						|
    import { BrowserMultiFormatReader } from 'https://cdn.jsdelivr.net/npm/@zxing/library@0.21.3/+esm';
 | 
						|
 | 
						|
    // constants
 | 
						|
    const codeReader = new BrowserMultiFormatReader();
 | 
						|
    const videoElement = document.getElementById('video');
 | 
						|
 | 
						|
 | 
						|
    // Start scanning for barcode
 | 
						|
    document.getElementById('startButton').addEventListener('click', async () => {
 | 
						|
        console.log('[DEBUG] Start button clicked')
 | 
						|
        try {
 | 
						|
            await navigator.mediaDevices.getUserMedia({ video: true });
 | 
						|
        } catch (err) {
 | 
						|
            alert("No camera found or no camera permission");
 | 
						|
            console.error("Could not access the camera:", err);
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        console.log('[DEBUG] Permission given and at least one device present');
 | 
						|
        const devices = await codeReader.listVideoInputDevices();
 | 
						|
        console.log('[DEBUG] Cameras found:', devices);
 | 
						|
        const rearCamera = devices.find(device => device.label.toLowerCase().includes('back'))
 | 
						|
            || devices.find(device => device.label.toLowerCase().includes('rear'))
 | 
						|
            || devices[0]; // fallback
 | 
						|
 | 
						|
        const selectedDeviceId = rearCamera?.deviceId;
 | 
						|
        await codeReader.decodeFromVideoDevice(selectedDeviceId, videoElement, async (result, err) => {
 | 
						|
            if (result) {
 | 
						|
                // Result found, this should post the barcode
 | 
						|
                const codeText = result.getText();
 | 
						|
                const baseURL = "{{url_for('add_meal.step3', input='!')}}";
 | 
						|
                window.location.href = baseURL.replace("!", encodeURIComponent(codeText));
 | 
						|
            }
 | 
						|
        })
 | 
						|
    })
 | 
						|
 | 
						|
    document.getElementById('stopButton').addEventListener('click', () => {
 | 
						|
        codeReader.reset();
 | 
						|
    });
 | 
						|
</script>
 | 
						|
{% endblock %} |