chore: remove dead code — 8 components, 5 libs, 4 API routes, 4 npm packages, 30+ scripts, dead CSS, dead exports
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 5s
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 5s
Removed unused components: - brainstorm-canvas, brainstorm-create-dialog, invite-dialog, manual-idea-dialog - note-inline-editor, profile-page-header, quota-paywall, label-management-dialog Removed dead lib files: - api-auth.ts, color-harmony-recommendation.ts, label-storage.ts, modern-color-options.ts - hooks/use-card-size-mode.ts Removed dead API routes: - ai/test-chat, ai/test-embeddings, ai/test-tags, admin/randomize-labels Removed unused npm packages: - cmdk, novel, tippy.js, react-force-graph-2d Cleaned dead CSS from globals.css: - acrylic-*, win11-shadow-*, muuri-grid/item, ai-glass, ai-tab-indicator, ai-send-btn, sidebar-view-toggle, memento-sidebar-depth Removed 29 orphan scripts and 3 root orphan files Cleaned dead exports from 8 lib files: - NOTE_TYPE_CONFIG, getPublishableKey, PROVIDER_DEFAULTS, useNotes/useNote/invalidateNote, etc.
This commit is contained in:
@@ -1,36 +0,0 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import prisma from '@/lib/prisma';
|
||||
import { LABEL_COLORS } from '@/lib/types';
|
||||
import { auth } from '@/auth';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
export async function POST() {
|
||||
try {
|
||||
const session = await auth()
|
||||
if (!session?.user?.id || (session.user as any).role !== 'ADMIN') {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
||||
}
|
||||
const labels = await prisma.label.findMany();
|
||||
const colors = Object.keys(LABEL_COLORS).filter(c => c !== 'gray'); // Exclude gray to force colors
|
||||
|
||||
const updates = labels.map((label: any) => {
|
||||
const randomColor = colors[Math.floor(Math.random() * colors.length)];
|
||||
return prisma.label.update({
|
||||
where: { id: label.id },
|
||||
data: { color: randomColor }
|
||||
});
|
||||
});
|
||||
|
||||
await prisma.$transaction(updates);
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
updated: updates.length,
|
||||
message: "All labels have been assigned a random non-gray color."
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
return NextResponse.json({ error: String(error) }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { getChatProvider } from '@/lib/ai/factory'
|
||||
import { getSystemConfig } from '@/lib/config'
|
||||
import { auth } from '@/auth'
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
const session = await auth()
|
||||
if (!session?.user?.id) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
||||
}
|
||||
if ((session.user as any).role !== 'ADMIN') {
|
||||
return NextResponse.json({ error: 'Forbidden' }, { status: 403 })
|
||||
}
|
||||
|
||||
try {
|
||||
const config = await getSystemConfig()
|
||||
const provider = getChatProvider(config)
|
||||
|
||||
const testMessage = 'Réponds en exactement 3 mots : quel est ton nom ?'
|
||||
|
||||
const startTime = Date.now()
|
||||
const response = await provider.generateText(testMessage)
|
||||
const endTime = Date.now()
|
||||
|
||||
if (!response || response.trim().length === 0) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
error: 'No response from chat provider',
|
||||
model: config.AI_MODEL_CHAT || 'granite4:latest',
|
||||
},
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
model: config.AI_MODEL_CHAT || 'granite4:latest',
|
||||
chatResponse: response.trim(),
|
||||
responseTime: endTime - startTime,
|
||||
})
|
||||
} catch (error: any) {
|
||||
const config = await getSystemConfig()
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
error: error.message || 'Unknown error',
|
||||
model: config.AI_MODEL_CHAT || 'granite4:latest',
|
||||
stack: process.env.NODE_ENV === 'development' ? error.stack : undefined,
|
||||
},
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { getEmbeddingsProvider } from '@/lib/ai/factory'
|
||||
import { getSystemConfig } from '@/lib/config'
|
||||
import { auth } from '@/auth'
|
||||
|
||||
function getProviderDetails(config: Record<string, string>, providerType: string) {
|
||||
const provider = providerType.toLowerCase()
|
||||
|
||||
switch (provider) {
|
||||
case 'ollama':
|
||||
return {
|
||||
provider: 'Ollama',
|
||||
baseUrl: config.OLLAMA_BASE_URL || 'http://localhost:11434',
|
||||
model: config.AI_MODEL_EMBEDDING || 'embeddinggemma:latest'
|
||||
}
|
||||
case 'openai':
|
||||
return {
|
||||
provider: 'OpenAI',
|
||||
baseUrl: 'https://api.openai.com/v1',
|
||||
model: config.AI_MODEL_EMBEDDING || 'text-embedding-3-small'
|
||||
}
|
||||
case 'custom':
|
||||
return {
|
||||
provider: 'Custom OpenAI',
|
||||
baseUrl: config.CUSTOM_OPENAI_BASE_URL || 'Not configured',
|
||||
model: config.AI_MODEL_EMBEDDING || 'text-embedding-3-small'
|
||||
}
|
||||
default:
|
||||
return {
|
||||
provider: provider,
|
||||
baseUrl: 'unknown',
|
||||
model: config.AI_MODEL_EMBEDDING || 'unknown'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
const session = await auth()
|
||||
if (!session?.user?.id) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
||||
}
|
||||
if ((session.user as any).role !== 'ADMIN') {
|
||||
return NextResponse.json({ error: 'Forbidden' }, { status: 403 })
|
||||
}
|
||||
|
||||
try {
|
||||
const config = await getSystemConfig()
|
||||
const provider = getEmbeddingsProvider(config)
|
||||
|
||||
const testText = 'test'
|
||||
const startTime = Date.now()
|
||||
const embeddings = await provider.getEmbeddings(testText)
|
||||
const endTime = Date.now()
|
||||
|
||||
if (!embeddings || embeddings.length === 0) {
|
||||
const providerType = config.AI_PROVIDER_EMBEDDING || 'ollama'
|
||||
const details = getProviderDetails(config, providerType)
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
error: 'No embeddings returned',
|
||||
provider: providerType,
|
||||
model: config.AI_MODEL_EMBEDDING || 'embeddinggemma:latest',
|
||||
details
|
||||
},
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
|
||||
const providerType = config.AI_PROVIDER_EMBEDDING || 'ollama'
|
||||
const details = getProviderDetails(config, providerType)
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
provider: providerType,
|
||||
model: config.AI_MODEL_EMBEDDING || 'embeddinggemma:latest',
|
||||
embeddingLength: embeddings.length,
|
||||
firstValues: embeddings.slice(0, 5),
|
||||
responseTime: endTime - startTime,
|
||||
details
|
||||
})
|
||||
} catch (error: any) {
|
||||
const config = await getSystemConfig()
|
||||
const providerType = config.AI_PROVIDER_EMBEDDING || 'ollama'
|
||||
const details = getProviderDetails(config, providerType)
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
error: error.message || 'Unknown error',
|
||||
provider: providerType,
|
||||
model: config.AI_MODEL_EMBEDDING || 'embeddinggemma:latest',
|
||||
details,
|
||||
stack: process.env.NODE_ENV === 'development' ? error.stack : undefined
|
||||
},
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { getTagsProvider } from '@/lib/ai/factory'
|
||||
import { getSystemConfig } from '@/lib/config'
|
||||
import { auth } from '@/auth'
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
const session = await auth()
|
||||
if (!session?.user?.id) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
||||
}
|
||||
if ((session.user as any).role !== 'ADMIN') {
|
||||
return NextResponse.json({ error: 'Forbidden' }, { status: 403 })
|
||||
}
|
||||
|
||||
try {
|
||||
const config = await getSystemConfig()
|
||||
const provider = getTagsProvider(config)
|
||||
|
||||
const testContent = "This is a test note about artificial intelligence and machine learning. It contains keywords like AI, ML, neural networks, and deep learning."
|
||||
|
||||
const startTime = Date.now()
|
||||
const tags = await provider.generateTags(testContent)
|
||||
const endTime = Date.now()
|
||||
|
||||
if (!tags || tags.length === 0) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
error: 'No tags generated',
|
||||
provider: config.AI_PROVIDER_TAGS || 'ollama',
|
||||
model: config.AI_MODEL_TAGS || 'granite4:latest'
|
||||
},
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
provider: config.AI_PROVIDER_TAGS || 'ollama',
|
||||
model: config.AI_MODEL_TAGS || 'granite4:latest',
|
||||
tags: tags,
|
||||
responseTime: endTime - startTime
|
||||
})
|
||||
} catch (error: any) {
|
||||
const config = await getSystemConfig()
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
error: error.message || 'Unknown error',
|
||||
provider: config.AI_PROVIDER_TAGS || 'ollama',
|
||||
model: config.AI_MODEL_TAGS || 'granite4:latest',
|
||||
stack: process.env.NODE_ENV === 'development' ? error.stack : undefined
|
||||
},
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -94,36 +94,10 @@
|
||||
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
||||
}
|
||||
|
||||
@utility acrylic-heavy {
|
||||
backdrop-filter: blur(40px) saturate(200%);
|
||||
-webkit-backdrop-filter: blur(40px) saturate(200%);
|
||||
}
|
||||
|
||||
@utility acrylic-light {
|
||||
background: rgba(255, 255, 255, 0.72);
|
||||
backdrop-filter: blur(24px) saturate(1.35);
|
||||
-webkit-backdrop-filter: blur(24px) saturate(1.35);
|
||||
}
|
||||
|
||||
@utility font-memento-serif {
|
||||
font-family: var(--font-memento-serif), ui-serif, Georgia, "Times New Roman", serif;
|
||||
}
|
||||
|
||||
@utility acrylic-dark {
|
||||
background: rgba(32, 32, 32, 0.75);
|
||||
backdrop-filter: blur(20px) saturate(1.5);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(1.5);
|
||||
}
|
||||
|
||||
@utility win11-shadow {
|
||||
box-shadow: var(--shadow-card-rest);
|
||||
transition: box-shadow var(--transition-normal);
|
||||
}
|
||||
|
||||
@utility win11-shadow-hover {
|
||||
box-shadow: var(--shadow-card-hover);
|
||||
}
|
||||
|
||||
@utility editor-body {
|
||||
font-size: var(--editor-body-size, 16px);
|
||||
}
|
||||
@@ -137,14 +111,6 @@ html.dark .memento-paper-texture {
|
||||
background-color: var(--background);
|
||||
}
|
||||
|
||||
.memento-sidebar-depth {
|
||||
box-shadow: 1px 0 10px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
html.dark .memento-sidebar-depth {
|
||||
box-shadow: 4px 0 24px -8px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
html:not(.dark) .memento-active-nav {
|
||||
background: linear-gradient(to right, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.4));
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
|
||||
@@ -164,12 +130,6 @@ html:not(.dark) .memento-active-nav {
|
||||
background: rgba(28, 28, 28, 0.2);
|
||||
}
|
||||
|
||||
.ai-glass {
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
.sidebar-shadow {
|
||||
box-shadow: 1px 0 10px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
@@ -188,41 +148,6 @@ html:not(.dark) .memento-active-nav {
|
||||
--ai-accent: #ACB995;
|
||||
}
|
||||
|
||||
/* Sidebar toggle view button (Notebooks / Agents) */
|
||||
.sidebar-view-toggle {
|
||||
display: flex;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
padding: 2px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.sidebar-view-toggle-btn {
|
||||
padding: 6px;
|
||||
border-radius: 999px;
|
||||
transition: all 150ms;
|
||||
color: var(--muted-foreground);
|
||||
}
|
||||
|
||||
.sidebar-view-toggle-btn:hover {
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.sidebar-view-toggle-btn.active {
|
||||
background: var(--foreground);
|
||||
color: var(--background);
|
||||
}
|
||||
|
||||
/* Dark mode toggle */
|
||||
html.dark .sidebar-view-toggle {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
html.dark .sidebar-view-toggle-btn.active {
|
||||
background: var(--primary);
|
||||
color: var(--primary-foreground);
|
||||
}
|
||||
|
||||
/* Inbox section separator */
|
||||
.sidebar-inbox-item {
|
||||
display: flex;
|
||||
@@ -254,16 +179,6 @@ html.dark .sidebar-inbox-item.active {
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
|
||||
/* Animated tab indicator for AI panel */
|
||||
.ai-tab-indicator {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
background: var(--foreground);
|
||||
}
|
||||
|
||||
/* Note date in editorial view */
|
||||
.note-date-badge {
|
||||
font-size: 11px;
|
||||
@@ -274,31 +189,12 @@ html.dark .sidebar-inbox-item.active {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
/* Persian/Arabic: avoid uppercase + wide tracking on mixed scripts; bidi class set in TSX */
|
||||
.note-date-badge.note-date-badge--locale-rtl {
|
||||
text-transform: none;
|
||||
letter-spacing: 0.08em;
|
||||
unicode-bidi: isolate;
|
||||
}
|
||||
|
||||
/* AI send button accent */
|
||||
.ai-send-btn {
|
||||
background: var(--ai-accent);
|
||||
color: white;
|
||||
border-radius: 8px;
|
||||
padding: 8px;
|
||||
transition: transform 100ms, opacity 100ms;
|
||||
}
|
||||
|
||||
.ai-send-btn:hover {
|
||||
opacity: 0.9;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.ai-send-btn:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
/* Dark mode active nav */
|
||||
html.dark .memento-active-nav {
|
||||
background: rgba(255, 255, 255, 0.09);
|
||||
@@ -1125,36 +1021,6 @@ html.font-system * {
|
||||
pointer-events: none !important;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
Muuri Grid Styles for Drag & Drop
|
||||
============================================ */
|
||||
.muuri-grid {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Note: Width is controlled by Tailwind classes (w-1/2, w-1/3, w-full, etc.) */
|
||||
.muuri-item {
|
||||
position: absolute;
|
||||
/* width: 100%; REMOVED - Don't override Tailwind size classes */
|
||||
}
|
||||
|
||||
.muuri-item.muuri-item-dragging {
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.muuri-item.muuri-item-releasing {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.muuri-item.muuri-item-hidden {
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
/* Ensure note cards work properly with Muuri */
|
||||
.muuri-item>* {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Force URLs/links to render LTR even in RTL mode */
|
||||
[dir="rtl"] .prose a {
|
||||
direction: ltr;
|
||||
|
||||
Reference in New Issue
Block a user