feat: comprehensive security and architecture improvements

- Add Zod validation schemas with strong password requirements (12+ chars, complexity)
- Implement rate limiting for authentication endpoints (registration, password reset)
- Remove duplicate MetricCard component, consolidate to ui/metric-card.tsx
- Update README.md to use pnpm commands consistently
- Enhance authentication security with 12-round bcrypt hashing
- Add comprehensive input validation for all API endpoints
- Fix security vulnerabilities in user registration and password reset flows

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-06-28 01:52:53 +02:00
parent 192f9497b4
commit 7f48a085bf
68 changed files with 8045 additions and 4542 deletions

View File

@ -1,14 +1,17 @@
'use client';
"use client";
import React from 'react';
import { TopQuestion } from '../lib/types';
import React from "react";
import { TopQuestion } from "../lib/types";
interface TopQuestionsChartProps {
data: TopQuestion[];
title?: string;
}
export default function TopQuestionsChart({ data, title = "Top 5 Asked Questions" }: TopQuestionsChartProps) {
export default function TopQuestionsChart({
data,
title = "Top 5 Asked Questions",
}: TopQuestionsChartProps) {
if (!data || data.length === 0) {
return (
<div className="bg-white p-6 rounded-lg shadow-sm border border-gray-200">
@ -21,7 +24,7 @@ export default function TopQuestionsChart({ data, title = "Top 5 Asked Questions
}
// Find the maximum count to calculate relative bar widths
const maxCount = Math.max(...data.map(q => q.count));
const maxCount = Math.max(...data.map((q) => q.count));
return (
<div className="bg-white p-6 rounded-lg shadow-sm border border-gray-200">
@ -29,7 +32,8 @@ export default function TopQuestionsChart({ data, title = "Top 5 Asked Questions
<div className="space-y-4">
{data.map((question, index) => {
const percentage = maxCount > 0 ? (question.count / maxCount) * 100 : 0;
const percentage =
maxCount > 0 ? (question.count / maxCount) * 100 : 0;
return (
<div key={index} className="relative">