feat: complete candle annotator implementation

- Created CandleChart component with lightweight-charts integration
- Implemented SvgOverlay component for line drawing
- Integrated all components in main page
- Fixed TypeScript and Tailwind CSS compatibility issues
- Added comprehensive README.md with project documentation
- Created DEPLOYMENT.md with setup and troubleshooting guide
- Downgraded to stable versions (Tailwind v3, lightweight-charts v4)
- All 59 tasks from OpenSpec completed
This commit is contained in:
Marko Djordjevic 2026-02-12 11:20:29 +01:00
parent 8d1e72579e
commit 23f18f405a
11 changed files with 8166 additions and 24 deletions

View file

@ -5,10 +5,11 @@ import { eq } from 'drizzle-orm';
export async function DELETE(
request: NextRequest,
{ params }: { params: { id: string } }
{ params }: { params: Promise<{ id: string }> }
) {
try {
const id = parseInt(params.id);
const { id: idParam } = await params;
const id = parseInt(idParam);
if (isNaN(id)) {
return NextResponse.json(

View file

@ -3,7 +3,7 @@ import Papa from 'papaparse';
import { db } from '@/lib/db';
import { candles } from '@/lib/db/schema';
export async function POST(request: NextRequest) {
export async function POST(request: NextRequest): Promise<NextResponse> {
try {
const formData = await request.formData();
const file = formData.get('file') as File;
@ -17,7 +17,7 @@ export async function POST(request: NextRequest) {
const text = await file.text();
return new Promise((resolve) => {
return new Promise<NextResponse>((resolve) => {
Papa.parse(text, {
header: true,
dynamicTyping: true,
@ -115,7 +115,7 @@ export async function POST(request: NextRequest) {
);
}
},
error: (error) => {
error: (error: any) => {
resolve(
NextResponse.json(
{ error: `CSV parsing error: ${error.message}` },

View file

@ -1,19 +1,26 @@
'use client';
import { useState } from 'react';
import { useState, useRef } from 'react';
import Toolbox, { Tool } from '@/components/Toolbox';
import FileUpload from '@/components/FileUpload';
import CandleChart, { CandleChartHandle } from '@/components/CandleChart';
export default function Home() {
const [activeTool, setActiveTool] = useState<Tool>(null);
const chartRef = useRef<CandleChartHandle>(null);
const handleExport = () => {
window.location.href = '/api/export';
};
const handleUploadSuccess = () => {
// TODO: Trigger chart refresh
console.log('Upload successful - refresh chart');
// Refresh chart data after successful upload
chartRef.current?.refreshData();
};
const handleAnnotationChange = () => {
// Refresh chart when annotations change
chartRef.current?.refreshData();
};
return (
@ -34,11 +41,12 @@ export default function Home() {
</aside>
{/* Main chart area */}
<main className="flex-1 flex items-center justify-center bg-background">
<div className="text-muted-foreground text-center">
<p className="text-lg">Upload a CSV file to view the candlestick chart</p>
<p className="text-sm mt-2">CSV format: time, open, high, low, close</p>
</div>
<main className="flex-1 relative">
<CandleChart
ref={chartRef}
activeTool={activeTool}
onAnnotationChange={handleAnnotationChange}
/>
</main>
</div>
);