rebrand: rename project from Dispensa Manager to EverShelf
- Update app name across all files (manifest, index.html, README, docs) - Update contact email to evershelfproject@gmail.com - Rename Docker service/container/volume to evershelf - Rename localStorage keys: dispensa_* → evershelf_* - Rename SQLite DB reference: dispensa.db → evershelf.db - Update SSH remote to dadaloop82/EverShelf - Update Apache conf file name to evershelf.conf - Update CI workflow Docker image/container names - Update cron job example path - Add data/dispensa.db to .gitignore to prevent accidental commit
This commit is contained in:
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
# Docker runtime files
|
# Docker runtime files
|
||||||
data/dispensa.db
|
data/evershelf.db
|
||||||
data/*.db-wal
|
data/*.db-wal
|
||||||
data/*.db-shm
|
data/*.db-shm
|
||||||
data/backups/
|
data/backups/
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
# Dispensa Manager - Configuration
|
# EverShelf - Configuration
|
||||||
# Copy this file to .env and fill in your values
|
# Copy this file to .env and fill in your values
|
||||||
# cp .env.example .env
|
# cp .env.example .env
|
||||||
|
|
||||||
|
|||||||
@@ -40,14 +40,14 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Build Docker image
|
- name: Build Docker image
|
||||||
run: docker build -t dispensa-test .
|
run: docker build -t evershelf-test .
|
||||||
|
|
||||||
- name: Test container starts
|
- name: Test container starts
|
||||||
run: |
|
run: |
|
||||||
docker run -d --name test-dispensa -p 8080:80 dispensa-test
|
docker run -d --name test-evershelf -p 8080:80 evershelf-test
|
||||||
sleep 5
|
sleep 5
|
||||||
curl -f http://localhost:8080/ || exit 1
|
curl -f http://localhost:8080/ || exit 1
|
||||||
docker stop test-dispensa
|
docker stop test-evershelf
|
||||||
|
|
||||||
validate-translations:
|
validate-translations:
|
||||||
name: Validate Translation Files
|
name: Validate Translation Files
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
.env
|
.env
|
||||||
|
|
||||||
# Data directory (user-specific runtime data)
|
# Data directory (user-specific runtime data)
|
||||||
|
data/evershelf.db
|
||||||
data/dispensa.db
|
data/dispensa.db
|
||||||
data/*.db-wal
|
data/*.db-wal
|
||||||
data/*.db-shm
|
data/*.db-shm
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
All notable changes to Dispensa Manager will be documented in this file.
|
All notable changes to EverShelf will be documented in this file.
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|||||||
+5
-5
@@ -1,4 +1,4 @@
|
|||||||
# Contributing to Dispensa Manager
|
# Contributing to EverShelf
|
||||||
|
|
||||||
Thank you for your interest in contributing! This guide will help you get started.
|
Thank you for your interest in contributing! This guide will help you get started.
|
||||||
|
|
||||||
@@ -7,8 +7,8 @@ Thank you for your interest in contributing! This guide will help you get starte
|
|||||||
1. **Fork** the repository
|
1. **Fork** the repository
|
||||||
2. **Clone** your fork:
|
2. **Clone** your fork:
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/YOUR_USERNAME/dispensa.git
|
git clone https://github.com/YOUR_USERNAME/EverShelf.git
|
||||||
cd dispensa
|
cd EverShelf
|
||||||
```
|
```
|
||||||
3. **Create a branch** from `develop`:
|
3. **Create a branch** from `develop`:
|
||||||
```bash
|
```bash
|
||||||
@@ -55,7 +55,7 @@ Translations are one of the easiest ways to contribute! Each language is a singl
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"app.title": "Dispensa Manager",
|
"app.title": "EverShelf",
|
||||||
"nav.dashboard": "Dashboard",
|
"nav.dashboard": "Dashboard",
|
||||||
"nav.inventory": "Inventario",
|
"nav.inventory": "Inventario",
|
||||||
...
|
...
|
||||||
@@ -110,7 +110,7 @@ node -c assets/js/app.js
|
|||||||
python3 -c "import json; json.load(open('translations/it.json'))"
|
python3 -c "import json; json.load(open('translations/it.json'))"
|
||||||
|
|
||||||
# Test Docker build
|
# Test Docker build
|
||||||
docker build -t dispensa-test .
|
docker build -t evershelf-test .
|
||||||
```
|
```
|
||||||
|
|
||||||
## 📝 Pull Request Process
|
## 📝 Pull Request Process
|
||||||
|
|||||||
+2
-2
@@ -29,8 +29,8 @@ RUN [ ! -f /var/www/html/.env ] && cp /var/www/html/.env.example /var/www/html/.
|
|||||||
RUN echo '<Directory /var/www/html>\n\
|
RUN echo '<Directory /var/www/html>\n\
|
||||||
AllowOverride All\n\
|
AllowOverride All\n\
|
||||||
Require all granted\n\
|
Require all granted\n\
|
||||||
</Directory>' > /etc/apache2/conf-available/dispensa.conf \
|
</Directory>' > /etc/apache2/conf-available/evershelf.conf \
|
||||||
&& a2enconf dispensa
|
&& a2enconf evershelf
|
||||||
|
|
||||||
# Expose port 80
|
# Expose port 80
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# 🏠 Dispensa Manager
|
# 🏠 EverShelf
|
||||||
|
|
||||||
> **Self-hosted pantry management system** — Track your food inventory, scan barcodes, get AI-powered recipe suggestions, and reduce waste.
|
> **Self-hosted pantry management system** — Track your food inventory, scan barcodes, get AI-powered recipe suggestions, and reduce waste.
|
||||||
|
|
||||||
@@ -71,8 +71,8 @@
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. Clone the repository
|
# 1. Clone the repository
|
||||||
git clone https://github.com/dadaloop82/dispensa.git
|
git clone https://github.com/dadaloop82/EverShelf.git
|
||||||
cd dispensa
|
cd EverShelf
|
||||||
|
|
||||||
# 2. Create configuration file
|
# 2. Create configuration file
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
@@ -88,8 +88,8 @@ docker compose up -d
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. Clone the repository
|
# 1. Clone the repository
|
||||||
git clone https://github.com/dadaloop82/dispensa.git
|
git clone https://github.com/dadaloop82/EverShelf.git
|
||||||
cd dispensa
|
cd EverShelf
|
||||||
|
|
||||||
# 2. Create configuration file
|
# 2. Create configuration file
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
@@ -127,7 +127,7 @@ TTS_ENABLED=true
|
|||||||
The app works out of the box with Apache if placed in the web root or a subdirectory. Make sure `mod_rewrite` is enabled and `AllowOverride All` is set.
|
The app works out of the box with Apache if placed in the web root or a subdirectory. Make sure `mod_rewrite` is enabled and `AllowOverride All` is set.
|
||||||
|
|
||||||
```apache
|
```apache
|
||||||
<Directory /var/www/html/dispensa>
|
<Directory /var/www/html/evershelf>
|
||||||
AllowOverride All
|
AllowOverride All
|
||||||
Require all granted
|
Require all granted
|
||||||
</Directory>
|
</Directory>
|
||||||
@@ -142,7 +142,7 @@ The app works out of the box with Apache if placed in the web root or a subdirec
|
|||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
server_name your-server.local;
|
server_name your-server.local;
|
||||||
root /var/www/html/dispensa;
|
root /var/www/html/evershelf;
|
||||||
index index.html;
|
index index.html;
|
||||||
|
|
||||||
location /api/ {
|
location /api/ {
|
||||||
@@ -176,7 +176,7 @@ Set up a cron job for smart shopping predictions:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Run every 5 minutes
|
# Run every 5 minutes
|
||||||
*/5 * * * * php /path/to/dispensa/api/cron_smart_shopping.php >> /path/to/dispensa/data/cron.log 2>&1
|
*/5 * * * * php /path/to/evershelf/api/cron_smart_shopping.php >> /path/to/evershelf/data/cron.log 2>&1
|
||||||
```
|
```
|
||||||
|
|
||||||
### Backup (Optional)
|
### Backup (Optional)
|
||||||
@@ -185,7 +185,7 @@ The included `backup.sh` creates local daily backups of your database:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Run daily at 3 AM
|
# Run daily at 3 AM
|
||||||
0 3 * * * /path/to/dispensa/backup.sh
|
0 3 * * * /path/to/evershelf/backup.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -193,7 +193,7 @@ The included `backup.sh` creates local daily backups of your database:
|
|||||||
## 🏗️ Architecture
|
## 🏗️ Architecture
|
||||||
|
|
||||||
```
|
```
|
||||||
dispensa/
|
evershelf/
|
||||||
├── index.html # Single-page application (SPA)
|
├── index.html # Single-page application (SPA)
|
||||||
├── manifest.json # PWA manifest
|
├── manifest.json # PWA manifest
|
||||||
├── .env.example # Configuration template
|
├── .env.example # Configuration template
|
||||||
@@ -211,7 +211,7 @@ dispensa/
|
|||||||
│ └── img/ # Static images
|
│ └── img/ # Static images
|
||||||
│
|
│
|
||||||
└── data/ # Runtime data (gitignored)
|
└── data/ # Runtime data (gitignored)
|
||||||
├── dispensa.db # SQLite database (auto-created)
|
├── evershelf.db # SQLite database (auto-created)
|
||||||
├── backups/ # Local DB backups
|
├── backups/ # Local DB backups
|
||||||
└── *.json # Token/cache files
|
└── *.json # Token/cache files
|
||||||
```
|
```
|
||||||
@@ -255,7 +255,7 @@ dispensa/
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Run PHP's built-in server for local development
|
# Run PHP's built-in server for local development
|
||||||
php -S localhost:8080 -t /path/to/dispensa
|
php -S localhost:8080 -t /path/to/evershelf
|
||||||
|
|
||||||
# Check PHP syntax
|
# Check PHP syntax
|
||||||
php -l api/index.php
|
php -l api/index.php
|
||||||
@@ -315,6 +315,6 @@ This project is licensed under the **MIT License** — see the [LICENSE](LICENSE
|
|||||||
|
|
||||||
## 👨💻 Author
|
## 👨💻 Author
|
||||||
|
|
||||||
**Stimpfl Daniel** — [dadaloop82@gmail.com](mailto:dadaloop82@gmail.com)
|
**Stimpfl Daniel** — [evershelfproject@gmail.com](mailto:evershelfproject@gmail.com)
|
||||||
|
|
||||||
- GitHub: [@dadaloop82](https://github.com/dadaloop82)
|
- GitHub: [@dadaloop82](https://github.com/dadaloop82)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
/**
|
/**
|
||||||
* Cron: pre-compute smart shopping list and save to cache.
|
* Cron: pre-compute smart shopping list and save to cache.
|
||||||
* Install with: crontab -e
|
* Install with: crontab -e
|
||||||
* *\/5 * * * * php /var/www/html/dispensa/api/cron_smart_shopping.php >> /var/www/html/dispensa/data/cron.log 2>&1
|
* *\/5 * * * * php /var/www/html/evershelf/api/cron_smart_shopping.php >> /var/www/html/evershelf/data/cron.log 2>&1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Only allow CLI execution — block HTTP access
|
// Only allow CLI execution — block HTTP access
|
||||||
|
|||||||
+3
-3
@@ -1,13 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Dispensa Manager - Database initialization, schema, and migrations.
|
* EverShelf - Database initialization, schema, and migrations.
|
||||||
* Uses SQLite with WAL journal mode for concurrent read/write performance.
|
* Uses SQLite with WAL journal mode for concurrent read/write performance.
|
||||||
*
|
*
|
||||||
* @author Stimpfl Daniel <dadaloop82@gmail.com>
|
* @author Stimpfl Daniel <evershelfproject@gmail.com>
|
||||||
* @license MIT
|
* @license MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
define('DB_PATH', __DIR__ . '/../data/dispensa.db');
|
define('DB_PATH', __DIR__ . '/../data/evershelf.db');
|
||||||
|
|
||||||
function getDB(): PDO {
|
function getDB(): PDO {
|
||||||
$isNew = !file_exists(DB_PATH);
|
$isNew = !file_exists(DB_PATH);
|
||||||
|
|||||||
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Dispensa Manager - Main API Router
|
* EverShelf - Main API Router
|
||||||
* Handles all CRUD operations for products, inventory, shopping lists,
|
* Handles all CRUD operations for products, inventory, shopping lists,
|
||||||
* AI-powered features (Gemini), and third-party integrations (Bring!, DupliClick).
|
* AI-powered features (Gemini), and third-party integrations (Bring!, DupliClick).
|
||||||
*
|
*
|
||||||
* @author Stimpfl Daniel <dadaloop82@gmail.com>
|
* @author Stimpfl Daniel <evershelfproject@gmail.com>
|
||||||
* @license MIT
|
* @license MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/**
|
/**
|
||||||
* Dispensa Manager - UI Styles
|
* EverShelf - UI Styles
|
||||||
* Mobile-first PWA design with CSS custom properties.
|
* Mobile-first PWA design with CSS custom properties.
|
||||||
*
|
*
|
||||||
* @author Stimpfl Daniel <dadaloop82@gmail.com>
|
* @author Stimpfl Daniel <evershelfproject@gmail.com>
|
||||||
* @license MIT
|
* @license MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
+24
-25
@@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
* Dispensa Manager - Main Application JS
|
* EverShelf - Main Application JS
|
||||||
* Complete pantry management with barcode scanning, AI identification,
|
* Complete pantry management with barcode scanning, AI identification,
|
||||||
* Bring! shopping list integration, recipe generation, and TTS cooking mode.
|
* Bring! shopping list integration, recipe generation, and TTS cooking mode.
|
||||||
*
|
*
|
||||||
* @author Stimpfl Daniel <dadaloop82@gmail.com>
|
* @author Stimpfl Daniel <evershelfproject@gmail.com>
|
||||||
* @license MIT
|
* @license MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ const API_BASE = 'api/index.php';
|
|||||||
// ===== i18n TRANSLATION SYSTEM =====
|
// ===== i18n TRANSLATION SYSTEM =====
|
||||||
let _i18nStrings = null; // current language translations (flat)
|
let _i18nStrings = null; // current language translations (flat)
|
||||||
let _i18nFallback = null; // Italian fallback (flat)
|
let _i18nFallback = null; // Italian fallback (flat)
|
||||||
let _currentLang = localStorage.getItem('dispensa_lang') || navigator.language?.slice(0, 2) || 'it';
|
let _currentLang = localStorage.getItem('evershelf_lang') || navigator.language?.slice(0, 2) || 'it';
|
||||||
const _SUPPORTED_LANGS = { it: 'Italiano', en: 'English', de: 'Deutsch' };
|
const _SUPPORTED_LANGS = { it: 'Italiano', en: 'English', de: 'Deutsch' };
|
||||||
if (!_SUPPORTED_LANGS[_currentLang]) _currentLang = 'it';
|
if (!_SUPPORTED_LANGS[_currentLang]) _currentLang = 'it';
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ async function loadTranslations(lang) {
|
|||||||
else _i18nStrings = _i18nFallback;
|
else _i18nStrings = _i18nFallback;
|
||||||
}
|
}
|
||||||
_currentLang = lang;
|
_currentLang = lang;
|
||||||
localStorage.setItem('dispensa_lang', lang);
|
localStorage.setItem('evershelf_lang', lang);
|
||||||
_applyI18nToLabels();
|
_applyI18nToLabels();
|
||||||
translatePage();
|
translatePage();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -170,9 +170,8 @@ function _populateLanguageSelector() {
|
|||||||
// Change language and reload the page
|
// Change language and reload the page
|
||||||
function changeLanguage(lang) {
|
function changeLanguage(lang) {
|
||||||
if (lang === _currentLang) return;
|
if (lang === _currentLang) return;
|
||||||
localStorage.setItem('dispensa_lang', lang);
|
localStorage.setItem('evershelf_lang', lang);
|
||||||
location.reload();
|
location.reload();
|
||||||
}
|
|
||||||
|
|
||||||
const LOCATIONS = {
|
const LOCATIONS = {
|
||||||
'dispensa': { icon: '🗄️', label: 'Dispensa' },
|
'dispensa': { icon: '🗄️', label: 'Dispensa' },
|
||||||
@@ -728,7 +727,7 @@ let _settingsDirty = false;
|
|||||||
function getSettings() {
|
function getSettings() {
|
||||||
if (!_settingsCache) {
|
if (!_settingsCache) {
|
||||||
try {
|
try {
|
||||||
_settingsCache = JSON.parse(localStorage.getItem('dispensa_settings') || '{}');
|
_settingsCache = JSON.parse(localStorage.getItem('evershelf_settings') || '{}');
|
||||||
} catch(e) { _settingsCache = {}; }
|
} catch(e) { _settingsCache = {}; }
|
||||||
}
|
}
|
||||||
const s = _settingsCache;
|
const s = _settingsCache;
|
||||||
@@ -746,7 +745,7 @@ function getSettings() {
|
|||||||
|
|
||||||
function saveSettingsToStorage(settings) {
|
function saveSettingsToStorage(settings) {
|
||||||
_settingsCache = settings;
|
_settingsCache = settings;
|
||||||
localStorage.setItem('dispensa_settings', JSON.stringify(settings));
|
localStorage.setItem('evershelf_settings', JSON.stringify(settings));
|
||||||
// Persist to DB
|
// Persist to DB
|
||||||
_settingsDirty = true;
|
_settingsDirty = true;
|
||||||
_debouncedSyncSettings();
|
_debouncedSyncSettings();
|
||||||
@@ -798,7 +797,7 @@ async function syncSettingsFromDB() {
|
|||||||
if (db[key] !== undefined) s[key] = db[key];
|
if (db[key] !== undefined) s[key] = db[key];
|
||||||
}
|
}
|
||||||
_settingsCache = s;
|
_settingsCache = s;
|
||||||
localStorage.setItem('dispensa_settings', JSON.stringify(s));
|
localStorage.setItem('evershelf_settings', JSON.stringify(s));
|
||||||
}
|
}
|
||||||
if (res.settings.review_confirmed) {
|
if (res.settings.review_confirmed) {
|
||||||
_reviewConfirmedCache = res.settings.review_confirmed;
|
_reviewConfirmedCache = res.settings.review_confirmed;
|
||||||
@@ -7716,7 +7715,7 @@ async function testTTS() {
|
|||||||
s.tts_rate = parseFloat(document.getElementById('setting-tts-rate')?.value) || 1;
|
s.tts_rate = parseFloat(document.getElementById('setting-tts-rate')?.value) || 1;
|
||||||
s.tts_pitch = parseFloat(document.getElementById('setting-tts-pitch')?.value) || 1;
|
s.tts_pitch = parseFloat(document.getElementById('setting-tts-pitch')?.value) || 1;
|
||||||
saveSettingsToStorage(s);
|
saveSettingsToStorage(s);
|
||||||
_speakBrowser('Test vocale Dispensa Manager. La sintesi vocale funziona correttamente.');
|
_speakBrowser('Test vocale EverShelf. La sintesi vocale funziona correttamente.');
|
||||||
if (statusEl) { statusEl.style.display = 'block'; statusEl.className = 'settings-status success'; statusEl.textContent = '✅ Riproduzione in corso — controlla l\'audio del dispositivo.'; }
|
if (statusEl) { statusEl.style.display = 'block'; statusEl.className = 'settings-status success'; statusEl.textContent = '✅ Riproduzione in corso — controlla l\'audio del dispositivo.'; }
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -7740,7 +7739,7 @@ async function testTTS() {
|
|||||||
}
|
}
|
||||||
if (statusEl) { statusEl.style.display = 'block'; statusEl.className = 'settings-status'; statusEl.textContent = '⏳ Invio in corso…'; }
|
if (statusEl) { statusEl.style.display = 'block'; statusEl.className = 'settings-status'; statusEl.textContent = '⏳ Invio in corso…'; }
|
||||||
try {
|
try {
|
||||||
const req = _buildTtsRequest('Test vocale Dispensa Manager', formSettings);
|
const req = _buildTtsRequest('Test vocale EverShelf', formSettings);
|
||||||
const res = await _ttsViaProxy(req);
|
const res = await _ttsViaProxy(req);
|
||||||
const data = await res.json().catch(() => ({}));
|
const data = await res.json().catch(() => ({}));
|
||||||
const httpCode = data.status || res.status;
|
const httpCode = data.status || res.status;
|
||||||
@@ -8932,7 +8931,7 @@ function _getMissingSetupSteps(serverSettings) {
|
|||||||
const srv = serverSettings || {};
|
const srv = serverSettings || {};
|
||||||
|
|
||||||
// Step 0 — language: missing only if never set at all (fresh install)
|
// Step 0 — language: missing only if never set at all (fresh install)
|
||||||
if (!localStorage.getItem('dispensa_lang') && !localStorage.getItem('dispensa_setup_done')) {
|
if (!localStorage.getItem('evershelf_lang') && !localStorage.getItem('evershelf_setup_done')) {
|
||||||
missing.push(0);
|
missing.push(0);
|
||||||
}
|
}
|
||||||
// Step 1 — Gemini API key (check both localStorage and server .env)
|
// Step 1 — Gemini API key (check both localStorage and server .env)
|
||||||
@@ -9083,10 +9082,10 @@ function setupWizardNav(dir) {
|
|||||||
|
|
||||||
// If language changed, apply it
|
// If language changed, apply it
|
||||||
if (realIndex === 0 && dir === 1 && _setupData.lang !== _currentLang) {
|
if (realIndex === 0 && dir === 1 && _setupData.lang !== _currentLang) {
|
||||||
localStorage.setItem('dispensa_lang', _setupData.lang);
|
localStorage.setItem('evershelf_lang', _setupData.lang);
|
||||||
localStorage.setItem('dispensa_setup_step', String(_setupStep + 1));
|
localStorage.setItem('evershelf_setup_step', String(_setupStep + 1));
|
||||||
localStorage.setItem('dispensa_setup_pending', JSON.stringify(_setupPendingSteps));
|
localStorage.setItem('evershelf_setup_pending', JSON.stringify(_setupPendingSteps));
|
||||||
localStorage.setItem('dispensa_setup_data', JSON.stringify(_setupData));
|
localStorage.setItem('evershelf_setup_data', JSON.stringify(_setupData));
|
||||||
location.reload();
|
location.reload();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -9112,24 +9111,24 @@ async function _finishSetup() {
|
|||||||
});
|
});
|
||||||
} catch(e) { /* will work locally */ }
|
} catch(e) { /* will work locally */ }
|
||||||
|
|
||||||
localStorage.setItem('dispensa_setup_done', '1');
|
localStorage.setItem('evershelf_setup_done', '1');
|
||||||
localStorage.removeItem('dispensa_setup_step');
|
localStorage.removeItem('evershelf_setup_step');
|
||||||
localStorage.removeItem('dispensa_setup_data');
|
localStorage.removeItem('evershelf_setup_data');
|
||||||
document.getElementById('setup-wizard').style.display = 'none';
|
document.getElementById('setup-wizard').style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _initApp() {
|
async function _initApp() {
|
||||||
// Check for setup wizard resume (after language change)
|
// Check for setup wizard resume (after language change)
|
||||||
const resumeStep = localStorage.getItem('dispensa_setup_step');
|
const resumeStep = localStorage.getItem('evershelf_setup_step');
|
||||||
const resumeData = localStorage.getItem('dispensa_setup_data');
|
const resumeData = localStorage.getItem('evershelf_setup_data');
|
||||||
const resumePending = localStorage.getItem('dispensa_setup_pending');
|
const resumePending = localStorage.getItem('evershelf_setup_pending');
|
||||||
if (resumeStep && resumePending) {
|
if (resumeStep && resumePending) {
|
||||||
try { Object.assign(_setupData, JSON.parse(resumeData)); } catch(e) {}
|
try { Object.assign(_setupData, JSON.parse(resumeData)); } catch(e) {}
|
||||||
try { _setupPendingSteps = JSON.parse(resumePending); } catch(e) {}
|
try { _setupPendingSteps = JSON.parse(resumePending); } catch(e) {}
|
||||||
_setupStep = parseInt(resumeStep) || 0;
|
_setupStep = parseInt(resumeStep) || 0;
|
||||||
localStorage.removeItem('dispensa_setup_step');
|
localStorage.removeItem('evershelf_setup_step');
|
||||||
localStorage.removeItem('dispensa_setup_data');
|
localStorage.removeItem('evershelf_setup_data');
|
||||||
localStorage.removeItem('dispensa_setup_pending');
|
localStorage.removeItem('evershelf_setup_pending');
|
||||||
document.getElementById('setup-wizard').style.display = '';
|
document.getElementById('setup-wizard').style.display = '';
|
||||||
_renderSetupStep();
|
_renderSetupStep();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Daily backup of Dispensa database (local only)
|
# Daily backup of EverShelf database (local only)
|
||||||
# The database is NOT pushed to remote repositories.
|
# The database is NOT pushed to remote repositories.
|
||||||
# Runs via cron: creates a local timestamped backup copy
|
# Runs via cron: creates a local timestamped backup copy
|
||||||
#
|
#
|
||||||
# Example crontab entry:
|
# Example crontab entry:
|
||||||
# 0 3 * * * /var/www/html/dispensa/backup.sh
|
# 0 3 * * * /var/www/html/evershelf/backup.sh
|
||||||
|
|
||||||
INSTALL_DIR="$(cd "$(dirname "$0")" && pwd)"
|
INSTALL_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
BACKUP_DIR="${INSTALL_DIR}/data/backups"
|
BACKUP_DIR="${INSTALL_DIR}/data/backups"
|
||||||
|
|
||||||
mkdir -p "$BACKUP_DIR"
|
mkdir -p "$BACKUP_DIR"
|
||||||
|
|
||||||
DB_FILE="${INSTALL_DIR}/data/dispensa.db"
|
DB_FILE="${INSTALL_DIR}/data/evershelf.db"
|
||||||
if [ ! -f "$DB_FILE" ]; then
|
if [ ! -f "$DB_FILE" ]; then
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
DATE=$(date '+%Y-%m-%d_%H%M')
|
DATE=$(date '+%Y-%m-%d_%H%M')
|
||||||
cp "$DB_FILE" "${BACKUP_DIR}/dispensa_${DATE}.db"
|
cp "$DB_FILE" "${BACKUP_DIR}/evershelf_${DATE}.db"
|
||||||
|
|
||||||
# Keep only the last 7 backups
|
# Keep only the last 7 backups
|
||||||
ls -t "${BACKUP_DIR}"/dispensa_*.db 2>/dev/null | tail -n +8 | xargs -r rm --
|
ls -t "${BACKUP_DIR}"/evershelf_*.db 2>/dev/null | tail -n +8 | xargs -r rm --
|
||||||
|
|||||||
+4
-4
@@ -1,12 +1,12 @@
|
|||||||
services:
|
services:
|
||||||
dispensa:
|
evershelf:
|
||||||
build: .
|
build: .
|
||||||
container_name: dispensa
|
container_name: evershelf
|
||||||
ports:
|
ports:
|
||||||
- "8080:80"
|
- "8080:80"
|
||||||
volumes:
|
volumes:
|
||||||
# Persist database and runtime data
|
# Persist database and runtime data
|
||||||
- dispensa_data:/var/www/html/data
|
- evershelf_data:/var/www/html/data
|
||||||
# Mount your local .env configuration
|
# Mount your local .env configuration
|
||||||
- ./.env:/var/www/html/.env:ro
|
- ./.env:/var/www/html/.env:ro
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -14,5 +14,5 @@ services:
|
|||||||
- TZ=Europe/Rome
|
- TZ=Europe/Rome
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
dispensa_data:
|
evershelf_data:
|
||||||
driver: local
|
driver: local
|
||||||
|
|||||||
+3
-3
@@ -1,8 +1,8 @@
|
|||||||
openapi: "3.1.0"
|
openapi: "3.1.0"
|
||||||
info:
|
info:
|
||||||
title: Dispensa Manager API
|
title: EverShelf API
|
||||||
description: |
|
description: |
|
||||||
REST API for Dispensa Manager — a self-hosted pantry management system.
|
REST API for EverShelf — a self-hosted pantry management system.
|
||||||
All endpoints use the query parameter `action` to determine the operation.
|
All endpoints use the query parameter `action` to determine the operation.
|
||||||
|
|
||||||
**Base URL:** `api/index.php?action={action_name}`
|
**Base URL:** `api/index.php?action={action_name}`
|
||||||
@@ -14,7 +14,7 @@ info:
|
|||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
contact:
|
contact:
|
||||||
name: Stimpfl Daniel
|
name: Stimpfl Daniel
|
||||||
email: dadaloop82@gmail.com
|
email: evershelfproject@gmail.com
|
||||||
license:
|
license:
|
||||||
name: MIT
|
name: MIT
|
||||||
url: https://opensource.org/licenses/MIT
|
url: https://opensource.org/licenses/MIT
|
||||||
|
|||||||
+4
-4
@@ -8,7 +8,7 @@
|
|||||||
<meta name="theme-color" content="#2d5016">
|
<meta name="theme-color" content="#2d5016">
|
||||||
<meta name="author" content="Stimpfl Daniel">
|
<meta name="author" content="Stimpfl Daniel">
|
||||||
<meta name="description" content="Self-hosted pantry manager with barcode scanning, AI identification, and shopping list integration.">
|
<meta name="description" content="Self-hosted pantry manager with barcode scanning, AI identification, and shopping list integration.">
|
||||||
<title>Dispensa Manager</title>
|
<title>EverShelf</title>
|
||||||
<link rel="manifest" href="manifest.json">
|
<link rel="manifest" href="manifest.json">
|
||||||
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🏠</text></svg>">
|
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🏠</text></svg>">
|
||||||
<link rel="stylesheet" href="assets/css/style.css?v=20260329a">
|
<link rel="stylesheet" href="assets/css/style.css?v=20260329a">
|
||||||
@@ -846,13 +846,13 @@
|
|||||||
<h4>🔒 Certificato HTTPS</h4>
|
<h4>🔒 Certificato HTTPS</h4>
|
||||||
<p class="settings-hint">Se il browser mostra l'errore "La connessione non è privata" (ERR_CERT_AUTHORITY_INVALID), devi installare il certificato CA nel dispositivo.</p>
|
<p class="settings-hint">Se il browser mostra l'errore "La connessione non è privata" (ERR_CERT_AUTHORITY_INVALID), devi installare il certificato CA nel dispositivo.</p>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<a href="ca.crt" download="Dispensa_CA.crt" class="btn btn-large btn-accent full-width" style="text-align:center;text-decoration:none;display:block">📥 Scarica Certificato CA</a>
|
<a href="ca.crt" download="EverShelf_CA.crt" class="btn btn-large btn-accent full-width" style="text-align:center;text-decoration:none;display:block">📥 Scarica Certificato CA</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings-hint" style="margin-top:12px;line-height:1.6">
|
<div class="settings-hint" style="margin-top:12px;line-height:1.6">
|
||||||
<strong>Istruzioni per Chrome (Android):</strong><br>
|
<strong>Istruzioni per Chrome (Android):</strong><br>
|
||||||
1. Scarica il certificato qui sopra<br>
|
1. Scarica il certificato qui sopra<br>
|
||||||
2. Vai in <em>Impostazioni → Sicurezza e privacy → Altre impostazioni di sicurezza → Installa da archivio dispositivo</em><br>
|
2. Vai in <em>Impostazioni → Sicurezza e privacy → Altre impostazioni di sicurezza → Installa da archivio dispositivo</em><br>
|
||||||
3. Seleziona il file <em>Dispensa_CA.crt</em> scaricato<br>
|
3. Seleziona il file <em>EverShelf_CA.crt</em> scaricato<br>
|
||||||
4. Scegli "CA" e conferma<br>
|
4. Scegli "CA" e conferma<br>
|
||||||
5. Riavvia Chrome<br><br>
|
5. Riavvia Chrome<br><br>
|
||||||
<strong>Istruzioni per Chrome (PC):</strong><br>
|
<strong>Istruzioni per Chrome (PC):</strong><br>
|
||||||
@@ -1109,7 +1109,7 @@
|
|||||||
<div class="modal-overlay" id="setup-wizard" style="display:none">
|
<div class="modal-overlay" id="setup-wizard" style="display:none">
|
||||||
<div class="modal-content setup-wizard-content" onclick="event.stopPropagation()">
|
<div class="modal-content setup-wizard-content" onclick="event.stopPropagation()">
|
||||||
<div class="setup-header">
|
<div class="setup-header">
|
||||||
<h2>🏠 Dispensa Manager</h2>
|
<h2>🏠 EverShelf</h2>
|
||||||
<div class="setup-progress" id="setup-progress"></div>
|
<div class="setup-progress" id="setup-progress"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="setup-body" id="setup-body"></div>
|
<div class="setup-body" id="setup-body"></div>
|
||||||
|
|||||||
+3
-3
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "Dispensa Manager",
|
"name": "EverShelf",
|
||||||
"short_name": "Dispensa",
|
"short_name": "EverShelf",
|
||||||
"description": "Gestione completa della dispensa di casa con scansione barcode",
|
"description": "Gestione completa della dispensa di casa con scansione barcode",
|
||||||
"start_url": "/dispensa/",
|
"start_url": "/evershelf/",
|
||||||
"display": "standalone",
|
"display": "standalone",
|
||||||
"background_color": "#f0f4e8",
|
"background_color": "#f0f4e8",
|
||||||
"theme_color": "#2d5016",
|
"theme_color": "#2d5016",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"app": {
|
"app": {
|
||||||
"name": "Dispensa Manager",
|
"name": "EverShelf",
|
||||||
"loading": "Laden..."
|
"loading": "Laden..."
|
||||||
},
|
},
|
||||||
"nav": {
|
"nav": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"app": {
|
"app": {
|
||||||
"name": "Dispensa Manager",
|
"name": "EverShelf",
|
||||||
"loading": "Loading..."
|
"loading": "Loading..."
|
||||||
},
|
},
|
||||||
"nav": {
|
"nav": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"app": {
|
"app": {
|
||||||
"name": "Dispensa Manager",
|
"name": "EverShelf",
|
||||||
"loading": "Caricamento..."
|
"loading": "Caricamento..."
|
||||||
},
|
},
|
||||||
"nav": {
|
"nav": {
|
||||||
|
|||||||
Reference in New Issue
Block a user