feat: Setup project with Vite and React

Initializes the Condopay frontend project using Vite, React, and TypeScript. Includes basic project structure, dependencies, and configuration for Tailwind CSS and React Router.
This commit is contained in:
2025-12-06 18:55:48 +01:00
parent 559c340f22
commit 79e249b638
26 changed files with 2364 additions and 8 deletions

116
server/db.js Normal file
View File

@@ -0,0 +1,116 @@
const mysql = require('mysql2/promise');
const bcrypt = require('bcryptjs');
require('dotenv').config();
// Configuration from .env or defaults
const dbConfig = {
host: process.env.DB_HOST || 'localhost',
user: process.env.DB_USER || 'root',
password: process.env.DB_PASS || '',
database: process.env.DB_NAME || 'condominio',
port: process.env.DB_PORT || 3306,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
};
const pool = mysql.createPool(dbConfig);
const initDb = async () => {
try {
const connection = await pool.getConnection();
console.log('Database connected successfully.');
// 1. Settings Table
await connection.query(`
CREATE TABLE IF NOT EXISTS settings (
id INT PRIMARY KEY DEFAULT 1,
condo_name VARCHAR(255) DEFAULT 'Il Mio Condominio',
default_monthly_quota DECIMAL(10, 2) DEFAULT 100.00,
current_year INT
)
`);
const [rows] = await connection.query('SELECT * FROM settings WHERE id = 1');
if (rows.length === 0) {
const currentYear = new Date().getFullYear();
await connection.query(
'INSERT INTO settings (id, condo_name, default_monthly_quota, current_year) VALUES (1, ?, ?, ?)',
['Condominio Demo', 100.00, currentYear]
);
}
// 2. Families Table
await connection.query(`
CREATE TABLE IF NOT EXISTS families (
id VARCHAR(36) PRIMARY KEY,
name VARCHAR(255) NOT NULL,
unit_number VARCHAR(50),
contact_email VARCHAR(255),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
`);
// 3. Payments Table
await connection.query(`
CREATE TABLE IF NOT EXISTS payments (
id VARCHAR(36) PRIMARY KEY,
family_id VARCHAR(36) NOT NULL,
amount DECIMAL(10, 2) NOT NULL,
date_paid DATETIME NOT NULL,
for_month INT NOT NULL,
for_year INT NOT NULL,
notes TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (family_id) REFERENCES families(id) ON DELETE CASCADE
)
`);
// 4. Users Table
await connection.query(`
CREATE TABLE IF NOT EXISTS users (
id VARCHAR(36) PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
name VARCHAR(255),
role VARCHAR(20) DEFAULT 'user',
phone VARCHAR(20),
family_id VARCHAR(36) NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (family_id) REFERENCES families(id) ON DELETE SET NULL
)
`);
// --- MIGRATION: CHECK FOR PHONE COLUMN ---
// This ensures existing databases get the new column without dropping the table
try {
const [columns] = await connection.query("SHOW COLUMNS FROM users LIKE 'phone'");
if (columns.length === 0) {
console.log('Adding missing "phone" column to users table...');
await connection.query("ALTER TABLE users ADD COLUMN phone VARCHAR(20)");
}
} catch (migError) {
console.warn("Migration check failed:", migError.message);
}
// Seed Admin User
const [admins] = await connection.query('SELECT * FROM users WHERE email = ?', ['fcarra79@gmail.com']);
if (admins.length === 0) {
const hashedPassword = await bcrypt.hash('Mr10921.', 10);
const { v4: uuidv4 } = require('uuid');
await connection.query(
'INSERT INTO users (id, email, password_hash, name, role) VALUES (?, ?, ?, ?, ?)',
[uuidv4(), 'fcarra79@gmail.com', hashedPassword, 'Amministratore', 'admin']
);
console.log('Default Admin user created.');
}
console.log('Database tables initialized.');
connection.release();
} catch (error) {
console.error('Database initialization failed:', error);
process.exit(1);
}
};
module.exports = { pool, initDb };