Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ gem "listen"
# Sass
gem "sassc-rails"

# Stimulus
gem "stimulus-rails"

# Not sure why
gem "net-imap", require: false
gem "net-pop", require: false
Expand Down
3 changes: 3 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,8 @@ GEM
sqlite3 (2.9.5-x86_64-linux-gnu)
sqlite3 (2.9.5-x86_64-linux-musl)
stackprof (0.2.28)
stimulus-rails (1.3.4)
railties (>= 6.0.0)
terrapin (1.1.1)
climate_control
thor (1.5.0)
Expand Down Expand Up @@ -536,6 +538,7 @@ DEPENDENCIES
spring
sqlite3
stackprof
stimulus-rails
tqdm
tzinfo-data
vanilla_nested
Expand Down
5 changes: 0 additions & 5 deletions app/assets/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,6 @@ body {
}
}

// Add support for Petite Vue "v-cloak" attribute.
[v-cloak] {
display: none;
}

.landing {
&-hero {
background-image: asset-url("landing/background.svg");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
import "@hotwired/turbo-rails";
import "chartkick/chart.js";
import "vanilla-nested";
import * as PetiteVue from "petite-vue";
import Quagga from "@ericblade/quagga2";
import Rails from "@rails/ujs";

// Start petite-vue on page and frame load
document.addEventListener("turbo:load", () => PetiteVue.createApp().mount());
document.addEventListener("turbo:frame-load", () => PetiteVue.createApp().mount());

// Globally mount Quagga
window.Quagga = Quagga;

Rails.start();

// Register a service worker
import "./pwa";

// Register stimulus controllers
import "./controllers";

// Globally mount some utils
import "./utils/filepicker";
import "./utils/modal";
Expand Down
9 changes: 9 additions & 0 deletions app/javascript/controllers/application.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Application } from "@hotwired/stimulus"

const application = Application.start()

// Configure Stimulus development experience
application.debug = false
window.Stimulus = application

export { application }
16 changes: 16 additions & 0 deletions app/javascript/controllers/current_dagschotel_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Controller } from "@hotwired/stimulus"

// Connects to data-controller="current-dagschotel"
export default class extends Controller {
static targets = [ "button" ]

startHover() {
this.buttonTarget.innerText = "Remove dagschotel";
this.buttonTarget.classList.add("is-danger");
}

endHover() {
this.buttonTarget.innerText = "Current dagschotel";
this.buttonTarget.classList.remove("is-danger");
}
}
8 changes: 8 additions & 0 deletions app/javascript/controllers/flash_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Controller } from "@hotwired/stimulus"

// Connects to data-controller="flash"
export default class extends Controller {
remove() {
this.element.remove();
}
}
29 changes: 29 additions & 0 deletions app/javascript/controllers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// This file is auto-generated by ./bin/rails stimulus:manifest:update
// Run that command whenever you add a new controller or create them with
// ./bin/rails generate stimulus controllerName

import { application } from "./application"

import CurrentDagschotelController from "./current_dagschotel_controller"
application.register("current-dagschotel", CurrentDagschotelController)

import FlashController from "./flash_controller"
application.register("flash", FlashController)

import NavbarController from "./navbar_controller"
application.register("navbar", NavbarController)

import OrderController from "./order_controller"
application.register("order", OrderController)

import ProductsController from "./products_controller"
application.register("products", ProductsController)

import ScannerController from "./scanner_controller"
application.register("scanner", ScannerController)

import StockController from "./stock_controller"
application.register("stock", StockController)

import UserController from "./user_controller"
application.register("user", UserController)
16 changes: 16 additions & 0 deletions app/javascript/controllers/navbar_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Controller } from "@hotwired/stimulus"

// Connects to data-controller="navbar"
export default class extends Controller {
static targets = [ "burger", "menu" ]

initialize() {
this.open = false;
}

toggleOpen() {
this.open = !this.open;
this.burgerTarget.classList.toggle("is-active", this.open);
this.menuTarget.classList.toggle("is-active", this.open);
}
}
22 changes: 22 additions & 0 deletions app/javascript/controllers/order_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Controller } from "@hotwired/stimulus"

// Connects to data-controller="order"
export default class extends Controller {
static targets = [ "billOverview", "spinner", "actualForm" ];

setLoading() {
this.billOverviewTarget.classList.add("is-hidden");
this.spinnerTarget.classList.remove("is-hidden");
}

submit(event) {
event.currentTarget.disabled = true;
event.currentTarget.value = "Please wait...";
this.actualFormTarget.submit();
}

addItem(event) {
this.setLoading();
window.closeModal('modalOrderProducts');
}
}
48 changes: 48 additions & 0 deletions app/javascript/controllers/products_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Controller } from "@hotwired/stimulus"

// Connects to data-controller="products"
export default class extends Controller {
static targets = [ "item", "placeholder", "tab" ]

initialize() {
this.tab = "all";
this.searchValue = "";
}

changeTab(event) {
this.tab = event.params.category;
this.tabTargets.forEach(element => element.closest("li").classList.remove("is-active"));
event.target.closest("li").classList.add("is-active");
this.updateItems();
}

search(event) {
this.searchValue = event.currentTarget.value;
this.updateItems();
}

updateItems() {
let anyMatched = false;
this.itemTargets.forEach(element => {
const matches = this.itemMatches(element.dataset.name, element.dataset.category)
anyMatched ||= matches;
element.classList.toggle('is-hidden', !matches);
});
this.placeholderTarget.classList.toggle('is-hidden', anyMatched);
}

itemMatches(name, category) {
// If the product doesn't match the category, return false
if (category && this.tab !== "all" && this.tab !== category) {
return false;
}

// If the product doesn't match the search query, return false
if (this.searchValue && !name.toLowerCase().includes(this.searchValue.toLowerCase())) {
return false;
}

return true;
}

}
73 changes: 73 additions & 0 deletions app/javascript/controllers/scanner_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { Controller } from "@hotwired/stimulus"

// Connects to data-controller="scanner"
export default class extends Controller {
static targets = [ "laser", "loader", "error", "errorTitle", "errorMessage" ];

initialize() {
this.scanner = new BarcodeScanner("#barcodeCanvas");
this.loading = true;
this.error = null;
}

connect() {
this.scanner.onDetected = (barcode) => {
// Update the hidden barcode field.
document.getElementById("orderBarcodeScannerFormInput").value = barcode.codeResult.code;

// Submit the form
const form = document.getElementById("orderBarcodeScannerForm");
if (form.requestSubmit) {
form.requestSubmit();
} else {
form.submit();
}

// Close modal
window.closeModal("modalOrderScanner");
}

this.scanner.onSuccess = () => {
this.loading = false;
this.updateViews();
}

this.scanner.onError = (error) => {
this.loading = false;
this.error = {};

if (error.name === "NotAllowedError") {
this.error.title = "Camera access denied!";
this.error.message = "Please allow camera access for this site and reload the webpage.";
} else {
this.error.title = error.name;
this.error.message = error.message;
}
this.updateViews();
}
this.updateViews();
}

init(event) {
if (event.currentTarget === this.element) {
this.scanner.init();
}
}

destroy() {
if (event.currentTarget === this.element) {
this.scanner.destroy();
this.loading = true;
this.error = null;
this.updateViews();
}
}

updateViews() {
this.laserTarget.classList.toggle("is-hidden", this.error || this.loading);
this.loaderTarget.classList.toggle("is-hidden", !this.loading);
this.errorTarget.classList.toggle("is-hidden", !this.error);
this.errorTitleTarget.innerText = this.error?.title ?? "";
this.errorMessageTarget.innerText = this.error?.message ?? "";
}
}
16 changes: 16 additions & 0 deletions app/javascript/controllers/stock_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Controller } from "@hotwired/stimulus"

// Connects to data-controller="stock"
export default class extends Controller {
static targets = [ "totalOutput", "readableTotalOutput" ]

connect() {
this.currentValue = Number.parseInt(this.element.dataset.currentStock);
}

setPurchasedStock(event) {
const purchasedValue = Number.parseInt(event.currentTarget.value);
this.totalOutputTarget.value = this.currentValue + purchasedValue;
this.readableTotalOutputTarget.innerText = this.currentValue + purchasedValue;
}
}
23 changes: 23 additions & 0 deletions app/javascript/controllers/user_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Controller } from "@hotwired/stimulus"

// Connects to data-controller="user"
export default class extends Controller {
static targets = [ "dagschotel", "dagschotelLoader", "avatar", "avatarLoader", "userLink" ]

orderedDagschotel(event) {
this.dagschotelTarget.classList.add("user-dagschotel--loading");
this.dagschotelTarget.disabled = true;
this.dagschotelLoaderTarget.classList.remove("is-hidden");
event.currentTarget.closest('form').submit();
}

openedUser() {
if (this.hasDagschotelTarget) {
this.dagschotelTarget.classList.add("is-hidden");
}
this.avatarTarget.classList.add("user-avatar--loading");
this.avatarLoaderTarget.classList.remove("is-hidden");
this.userLinkTarget.disabled = true;
}

}
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions app/views/layouts/_flash.html.erb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<% flash.each do |type, msg| %>
<% if flash_is_notification?(type) %>
<div v-scope="{ open: true }" class="notification <%= isLight ? 'is-light' : '' %> <%= flash_class(type) %>" v-show="open">
<div class="notification <%= isLight ? 'is-light' : '' %> <%= flash_class(type) %>" data-controller="flash">
<!-- Close button -->
<button class="delete" @click="open = false"></button>
<button class="delete" data-action="flash#remove"></button>

<!-- Message -->
<%= msg %>
Expand Down
6 changes: 3 additions & 3 deletions app/views/layouts/_navbar.html.erb
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
<nav
v-scope="{ open: false }"
class="navbar <%= controller_name == 'landing' || current_user.koelkast ? 'is-primary is-raised' : 'is-transparent' %>"
data-controller="navbar"
>
<div class="container">
<!-- Brand -->
<div class="navbar-brand">
<%= link_to "Tap", root_path, class: "navbar-title" %>

<a role="button" class="navbar-burger" :class="open ? 'is-active' : ''" aria-label="menu" aria-expanded="false" @click="open = !open">
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-navbar-target="burger" data-action="navbar#toggleOpen">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>

<!-- Menu -->
<div class="navbar-menu" :class="open ? 'is-active' : ''">
<div class="navbar-menu" data-navbar-target="menu">

<div class="navbar-start">
</div>
Expand Down
Loading