6 Commits

Author SHA1 Message Date
c0b0edc00e Fix: Improve RPC error handling and routing
- Changed from rpcApp.use to rpcApp.all for better route handling
- Added proper error handling with try-catch
- Return 404 for unmatched routes instead of calling next()
- Return 500 for internal server errors
- Improves RPC endpoint reliability and debugging
2025-10-02 01:09:46 +02:00
9a104e8862 Optimize: Improve table column widths and text truncation
- Added table-fixed layout for consistent column widths
- Set specific column widths: Behandlung (2/5), Kategorie (1/6), Dauer (1/12), Preis (1/12), Aktionen (1/6)
- Truncate long descriptions to 50 characters with tooltip
- Added truncate class to prevent text overflow
- Ensures all columns are always visible without horizontal scrolling
2025-10-02 01:03:28 +02:00
84fc9ee890 Fix: Enable horizontal scrolling for treatments table
- Changed overflow-hidden to overflow-x-auto
- Fixes missing Edit/Delete buttons in treatments table
- Allows horizontal scrolling when table is too wide
- Resolves CSS layout issue in production
2025-10-02 00:58:42 +02:00
277be954b7 Fix: Remove duplicate /assets/ prefix from manifest paths
- Manifest already includes 'assets/' prefix
- Fixes double /assets/assets/ paths in production
- Ensures correct asset loading
2025-10-02 00:51:52 +02:00
65a0b8c823 Fix: Correct Vite manifest key lookup
- Changed from 'src/client/main.tsx' to 'index.html' to match actual manifest
- Fixes production asset loading
- Resolves empty page issue in production mode
2025-10-02 00:49:53 +02:00
1285560f62 Fix: Add manifest: true to Vite build config
- Enables Vite manifest generation for production builds
- Fixes CSS loading issues in production
- Resolves missing buttons in admin treatments page
- Ensures proper asset path resolution
2025-10-02 00:40:35 +02:00
4 changed files with 35 additions and 26 deletions

View File

@@ -197,23 +197,23 @@ export function AdminTreatments() {
</div>
)}
<div className="bg-white rounded-lg shadow-lg overflow-hidden">
<table className="w-full">
<div className="bg-white rounded-lg shadow-lg overflow-x-auto">
<table className="w-full table-fixed">
<thead className="bg-gray-50">
<tr>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
<th className="w-2/5 px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Behandlung
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
<th className="w-1/6 px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Kategorie
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
<th className="w-1/12 px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Dauer
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
<th className="w-1/12 px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Preis
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
<th className="w-1/6 px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Aktionen
</th>
</tr>
@@ -221,22 +221,26 @@ export function AdminTreatments() {
<tbody className="bg-white divide-y divide-gray-200">
{treatments?.map((treatment) => (
<tr key={treatment.id}>
<td className="px-6 py-4 whitespace-nowrap">
<td className="px-6 py-4">
<div>
<div className="text-sm font-medium text-gray-900">{treatment.name}</div>
<div className="text-sm text-gray-500">{treatment.description}</div>
<div className="text-sm font-medium text-gray-900 truncate">{treatment.name}</div>
<div className="text-sm text-gray-500 truncate" title={treatment.description}>
{treatment.description.length > 50
? `${treatment.description.substring(0, 50)}...`
: treatment.description}
</div>
</div>
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
<td className="px-6 py-4 text-sm text-gray-900 truncate">
{treatment.category}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
<td className="px-6 py-4 text-sm text-gray-900">
{treatment.duration} Min
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
<td className="px-6 py-4 text-sm text-gray-900">
{(treatment.price / 100).toFixed(2)}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium space-x-2">
<td className="px-6 py-4 text-sm font-medium space-x-2">
<button
onClick={() => handleEdit(treatment)}
className="text-pink-600 hover:text-pink-900"

View File

@@ -14,11 +14,11 @@ export function clientEntry(c: Context<BlankEnv>) {
// Read Vite manifest to get the correct file names
const manifestPath = join(process.cwd(), 'dist', '.vite', 'manifest.json');
const manifest = JSON.parse(readFileSync(manifestPath, 'utf-8'));
const entry = manifest['src/client/main.tsx'];
const entry = manifest['index.html'];
if (entry) {
jsFile = `/assets/${entry.file}`;
jsFile = `/${entry.file}`;
if (entry.css) {
cssFiles = entry.css.map((css: string) => `/assets/${css}`);
cssFiles = entry.css.map((css: string) => `/${css}`);
}
}
} catch (error) {

View File

@@ -7,15 +7,19 @@ export const rpcApp = new Hono();
const handler = new RPCHandler(router);
rpcApp.use("/*", async (c, next) => {
const { matched, response } = await handler.handle(c.req.raw, {
prefix: "/rpc",
});
rpcApp.all("/*", async (c) => {
try {
const { matched, response } = await handler.handle(c.req.raw, {
prefix: "/rpc",
});
if (matched) {
return c.newResponse(response.body, response);
if (matched) {
return c.newResponse(response.body, response);
}
return c.json({ error: "Not found" }, 404);
} catch (error) {
console.error("RPC Handler error:", error);
return c.json({ error: "Internal server error" }, 500);
}
await next();
return;
});

View File

@@ -23,6 +23,7 @@ export default defineConfig(({ mode }) => {
publicDir: "public",
build: {
outDir: "dist",
manifest: true,
rollupOptions: {
input: "index.html"
}