the hourly rate is not being saved

This commit is contained in:
Leon Serfaty G
2025-07-17 11:21:35 +00:00
parent 5f38178a60
commit 6a1d37bdc7
5 changed files with 139 additions and 5 deletions
+27 -4
View File
@@ -15,22 +15,45 @@ function seed() {
)
`);
// Create settings table if it doesn't exist
db.exec(`
CREATE TABLE IF NOT EXISTS settings (
key TEXT PRIMARY KEY,
value TEXT
)
`);
// Check if the admin user already exists
const stmt = db.prepare('SELECT * FROM users WHERE email = ?');
const adminUser = stmt.get('admin@example.com');
const userStmt = db.prepare('SELECT * FROM users WHERE email = ?');
const adminUser = userStmt.get('admin@example.com');
if (!adminUser) {
// Insert the default admin user
// In a real application, you should hash the password!
const insert = db.prepare(
const insertUser = db.prepare(
"INSERT INTO users (email, password, name) VALUES (?, ?, ?)"
);
insert.run("admin@example.com", "password", "Admin User");
insertUser.run("admin@example.com", "password", "Admin User");
console.log('Admin user created.');
} else {
console.log('Admin user already exists.');
}
// Check if the hourly_rate setting already exists
const settingStmt = db.prepare('SELECT * FROM settings WHERE key = ?');
const hourlyRateSetting = settingStmt.get('hourly_rate');
if (!hourlyRateSetting) {
// Insert the default hourly rate
const insertSetting = db.prepare(
"INSERT INTO settings (key, value) VALUES (?, ?)"
);
insertSetting.run("hourly_rate", "100");
console.log('Default hourly rate set.');
} else {
console.log('Hourly rate setting already exists.');
}
console.log('Seeding complete.');
}
+6
View File
@@ -53,6 +53,12 @@ export default function AdminLayout({
Email
</SidebarMenuSubButton>
</SidebarMenuSubItem>
<SidebarMenuSubItem>
<SidebarMenuSubButton href="/admin/settings/hourly-rate" >
<Settings />
Hourly Rate
</SidebarMenuSubButton>
</SidebarMenuSubItem>
</SidebarMenuSub>
</SidebarMenuItem>
</SidebarMenu>
@@ -0,0 +1,71 @@
"use client";
import { useEffect, useState, useTransition } from 'react';
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { useToast } from "@/hooks/use-toast";
import { getSetting, setSetting } from '@/lib/actions/settings';
const HourlyRateSettingsPage = () => {
const { toast } = useToast();
const [hourlyRate, setHourlyRate] = useState('');
const [isPending, startTransition] = useTransition();
useEffect(() => {
async function fetchHourlyRate() {
const rate = await getSetting('hourly_rate');
if (rate) {
setHourlyRate(rate);
}
}
fetchHourlyRate();
}, []);
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
startTransition(async () => {
try {
await setSetting('hourly_rate', hourlyRate);
toast({ title: "Hourly Rate Saved", description: "The hourly rate has been updated successfully." });
} catch (error) {
console.error("Failed to save hourly rate:", error);
toast({ title: "Error", description: "Failed to save hourly rate.", variant: "destructive" });
}
});
};
return (
<Card className="max-w-2xl">
<CardHeader>
<CardTitle>Hourly Rate Settings</CardTitle>
<CardDescription>
Set the default hourly rate used for project estimations.
</CardDescription>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="flex flex-col gap-4">
<div className="flex flex-col gap-2">
<Label htmlFor="hourlyRate">Hourly Rate ($)</Label>
<Input
id="hourlyRate"
name="hourlyRate"
type="number"
step="0.01"
placeholder="e.g., 100.00"
value={hourlyRate}
onChange={(e) => setHourlyRate(e.target.value)}
required
/>
</div>
<Button type="submit" className="self-start" disabled={isPending}>
{isPending ? 'Saving...' : 'Save Hourly Rate'}
</Button>
</form>
</CardContent>
</Card>
);
};
export default HourlyRateSettingsPage;
+26
View File
@@ -0,0 +1,26 @@
'use server';
import db from '@/lib/db';
export async function getSetting(key: string): Promise<string | null> {
try {
const stmt = db.prepare('SELECT value FROM settings WHERE key = ?');
const result = stmt.get(key) as { value: string } | undefined;
return result?.value ?? null;
} catch (error) {
console.error(`Failed to get setting "${key}":`, error);
return null;
}
}
export async function setSetting(key: string, value: string): Promise<void> {
try {
const stmt = db.prepare(
'INSERT INTO settings (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value'
);
stmt.run(key, value);
} catch (error) {
console.error(`Failed to set setting "${key}":`, error);
throw new Error(`Could not update setting for ${key}`);
}
}
+9 -1
View File
@@ -3,7 +3,7 @@ import Database from 'better-sqlite3';
// Use a file-based database in development
const db = new Database('local.db');
// Create the users table if it doesn't exist
// Create the tables if they don't exist
db.exec(`
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -13,4 +13,12 @@ db.exec(`
)
`);
db.exec(`
CREATE TABLE IF NOT EXISTS settings (
key TEXT PRIMARY KEY,
value TEXT
)
`);
export default db;