Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 16 additions & 14 deletions apps/api/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,6 @@

import authMiddleware from './middleware/authMiddleware.js';
import antraegeRouter from './routes/antraege/index.js';
import campaignCanvasRoute from './routes/sharepic/sharepic_canvas/campaign_canvas.js';
import veranstaltungCanvasRoute from './routes/sharepic/sharepic_canvas/veranstaltung_canvas.js';
import profilbildCanvasRoute from './routes/sharepic/sharepic_canvas/profilbild_canvas.js';
import simpleCanvasRoute from './routes/sharepic/sharepic_canvas/simple_canvas.js';
import campaignGenerateRoute from './routes/sharepic/sharepic_claude/campaign_generate.js';
import sharepicClaudeRoute, {
handleClaudeRequest,
} from './routes/sharepic/sharepic_claude/index.js';
import * as sharepicGenerationService from './services/chat/sharepicGenerationService.js';
import aiImageModificationRouter from './routes/sharepic/sharepic_canvas/aiImageModification.js';
import imageUploadRouter from './routes/sharepic/sharepic_canvas/imageUploadRouter.js';
import processTextRouter from './routes/sharepic/sharepic_canvas/processTextRouter.js';
import editSessionRouter from './routes/sharepic/editSession.js';
import etherpadRoute from './routes/etherpad/etherpadController.js';
import {
Expand Down Expand Up @@ -45,11 +33,22 @@ import promptRoute from './routes/sharepic/promptRoute.js';
import planModeRouter from './routes/plan-mode/index.js';
import scannerRouter from './routes/scanner/index.js';
import protokollRouter from './routes/protokoll/index.js';
import aiImageModificationRouter from './routes/sharepic/sharepic_canvas/aiImageModification.js';
import campaignCanvasRoute from './routes/sharepic/sharepic_canvas/campaign_canvas.js';
import sharepicDreizeilenCanvasRoute from './routes/sharepic/sharepic_canvas/dreizeilen_canvas.js';
import imageUploadRouter from './routes/sharepic/sharepic_canvas/imageUploadRouter.js';
import imagineLabelCanvasRoute from './routes/sharepic/sharepic_canvas/imagine_label_canvas.js';
import infoSharepicCanvasRoute from './routes/sharepic/sharepic_canvas/info_canvas.js';
import processTextRouter from './routes/sharepic/sharepic_canvas/processTextRouter.js';
import profilbildCanvasRoute from './routes/sharepic/sharepic_canvas/profilbild_canvas.js';
import simpleCanvasRoute from './routes/sharepic/sharepic_canvas/simple_canvas.js';
import veranstaltungCanvasRoute from './routes/sharepic/sharepic_canvas/veranstaltung_canvas.js';
import zitatSharepicCanvasRoute from './routes/sharepic/sharepic_canvas/zitat_canvas.js';
import zitatPureSharepicCanvasRoute from './routes/sharepic/sharepic_canvas/zitat_pure_canvas.js';
import campaignGenerateRoute from './routes/sharepic/sharepic_claude/campaign_generate.js';
import sharepicClaudeRoute, {
handleClaudeRequest,
} from './routes/sharepic/sharepic_claude/index.js';
import {
universalRouter,
redeRouter,
Expand All @@ -63,6 +62,7 @@ import {
leichteSpracheRouter as leichteSpracheRoute,
} from './routes/texte/index.js';
import { recentValuesRouter } from './routes/user/index.js';
import * as sharepicGenerationService from './services/chat/sharepicGenerationService.js';
import { createLogger } from './utils/logger.js';
import { RouteStatsTracker } from './utils/routeStats.js';

Expand Down Expand Up @@ -263,7 +263,9 @@ export async function setupRoutes(app: Application): Promise<void> {

// Debug: log all requests to /api/releases/*
app.use('/api/releases', (req, res, next) => {
console.log(`[Routes] Request to /api/releases: ${req.method} ${req.path} (originalUrl: ${req.originalUrl})`);
console.log(
`[Routes] Request to /api/releases: ${req.method} ${req.path} (originalUrl: ${req.originalUrl})`
);
next();
});
app.use('/api/releases', releasesRouter);
Expand Down Expand Up @@ -300,7 +302,7 @@ export async function setupRoutes(app: Application): Promise<void> {

// Web redirect to frontend imagine (KI image studio)
app.get('/web', (req: Request, res: Response) => {
res.redirect('http://localhost:3000/imagine');
res.redirect(`${req.protocol}://${req.get('host')}/imagine`);
});

// Periodic flush of route stats to database
Expand Down
21 changes: 18 additions & 3 deletions apps/api/routes/share/shareController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
* Handles sharing of images and videos with public links
*/

import express, { Request, Response, Router } from 'express';
import path from 'path';
import fs from 'fs';
import path from 'path';

import express, { type Request, type Response, type Router } from 'express';

import { requireAuth } from '../../middleware/authMiddleware.js';
import { createLogger } from '../../utils/logger.js';
import { redisClient } from '../../utils/redis/index.js';

import type { AuthenticatedRequest } from '../../middleware/types.js';
import type { SharedMediaRow, ShareResult } from '../../types/media.js';

Expand Down Expand Up @@ -605,7 +608,19 @@ router.get(
const userId = req.user!.id;
const limit = Math.min(parseInt(req.query.limit as string) || 6, 20);

const service = await getSharedMediaService();
let service;
try {
service = await getSharedMediaService();
} catch (initError) {
log.warn('SharedMediaService unavailable, returning empty result:', initError);
return res.json({
success: true,
shares: [],
count: 0,
limit,
});
}

const allShares = await service.getUserShares(userId, 'image');
const recentShares = allShares.slice(0, limit);

Expand Down
6 changes: 4 additions & 2 deletions apps/web/src/components/common/ExportDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ import {
} from '../utils/contentExtractor';

// Type assertions for JS functions that return Promises
const extractPlainText = extractPlainTextJs as (content: unknown) => Promise<string>;
const extractFormattedText = extractFormattedTextJs as (content: unknown) => Promise<string>;
const extractPlainText = extractPlainTextJs as unknown as (content: unknown) => Promise<string>;
const extractFormattedText = extractFormattedTextJs as unknown as (
content: unknown
) => Promise<string>;
import '../../assets/styles/components/actions/exportToDocument.css';

interface ExportDropdownProps {
Expand Down
1 change: 0 additions & 1 deletion apps/web/src/components/common/ImageSlider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ const loadImageGallery = async () => {
const [galleryModule, _styleSheet] = await Promise.all([
// @ts-expect-error - react-image-gallery types are missing
import('react-image-gallery'),
// @ts-expect-error - CSS import
import('react-image-gallery/styles/css/image-gallery.css'),
]);

Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/components/utils/commonFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import {
} from './contentExtractor';

// Type assertions for JS functions that return Promises
const extractPlainText = extractPlainTextJs as (content: unknown) => Promise<string>;
const extractHTMLContent = extractHTMLContentJs as (content: unknown) => Promise<string>;
const extractPlainText = extractPlainTextJs as unknown as (content: unknown) => Promise<string>;
const extractHTMLContent = extractHTMLContentJs as unknown as (content: unknown) => Promise<string>;

// Type definitions
type SetStateAction<T> = T | ((prevState: T) => T);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ const ProfileInfoTabContainer = ({

const handleToggleIgelModus = async () => {
try {
await updateUserBetaFeatures({ igel: !igelActive });
await updateUserBetaFeatures('igel', !igelActive);
onSuccessMessage(igelActive ? 'IGEL-Modus deaktiviert' : 'IGEL-Modus aktiviert');
} catch (error) {
console.error('Failed to toggle IGEL mode:', error);
Expand All @@ -325,6 +325,8 @@ const ProfileInfoTabContainer = ({

const isLoading = isLoadingProfile;

if (!user) return null;

return (
<>
<ProfileView
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,6 @@ const ImageStudioCategorySelector: React.FC = () => {
label: 'Profilbild',
description: 'Erstelle ein Porträt mit grünem Hintergrund',
Icon: PiUser,
previewImage: '/imagine/previews/profilbild-preview.png',
directType: IMAGE_STUDIO_TYPES.PROFILBILD,
isComingSoon: true,
},
Expand Down
28 changes: 13 additions & 15 deletions apps/web/src/features/notebook/components/NotebookEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { AnimatePresence, motion } from 'motion/react';
import { useState, useEffect, useCallback, useRef, type ComponentType, type DragEvent } from 'react';
import {
useState,
useEffect,
useCallback,
useRef,
type ComponentType,
type DragEvent,
} from 'react';
import { useForm } from 'react-hook-form';
import { HiCheckCircle, HiArrowLeft, HiUpload, HiX } from 'react-icons/hi';

Expand Down Expand Up @@ -108,13 +115,11 @@ const NotebookEditor = ({

try {
const doc = await uploadFileOnly(file, file.name);
setUploadedDocument(doc);
setUploadedDocument({ id: doc.id, title: doc.title || file.name });
setValue('name', doc.title.replace(/\.[^/.]+$/, ''), { shouldValidate: true });
setStep(2);
} catch (err) {
setUploadError(
err instanceof Error ? err.message : 'Fehler beim Hochladen der Datei'
);
setUploadError(err instanceof Error ? err.message : 'Fehler beim Hochladen der Datei');
} finally {
setIsUploading(false);
}
Expand Down Expand Up @@ -246,22 +251,15 @@ const NotebookEditor = ({
) : (
<div className="dropzone-content">
<HiUpload size={28} className="dropzone-icon" />
<p className="dropzone-text">
Datei hier ablegen oder klicken
</p>
<p className="dropzone-hint">
PDF, DOCX, TXT, MD, ODT, RTF (max. 50 MB)
</p>
<p className="dropzone-text">Datei hier ablegen oder klicken</p>
<p className="dropzone-hint">PDF, DOCX, TXT, MD, ODT, RTF (max. 50 MB)</p>
</div>
)}
</div>

{uploadError && (
<p className="notebook-upload-error">{uploadError}</p>
)}
{uploadError && <p className="notebook-upload-error">{uploadError}</p>}
</div>
</div>

</motion.div>
) : (
<motion.div
Expand Down
8 changes: 4 additions & 4 deletions apps/web/src/utils/desktopSecureStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export async function getAccessToken(): Promise<string | null> {
try {
const store = await getStore();
if (store) {
const token = await store.get<string>(ACCESS_TOKEN_KEY);
const token = (await store.get(ACCESS_TOKEN_KEY)) as string | undefined;
return token || null;
}
} catch (error) {
Expand All @@ -145,7 +145,7 @@ export async function getRefreshToken(): Promise<string | null> {
try {
const store = await getStore();
if (store) {
const token = await store.get<string>(REFRESH_TOKEN_KEY);
const token = (await store.get(REFRESH_TOKEN_KEY)) as string | undefined;
return token || null;
}
} catch (error) {
Expand All @@ -165,7 +165,7 @@ export async function getStoredUser(): Promise<StoredUser | null> {
try {
const store = await getStore();
if (store) {
const user = await store.get<StoredUser>(USER_KEY);
const user = (await store.get(USER_KEY)) as StoredUser | undefined;
return user || null;
}
} catch (error) {
Expand Down Expand Up @@ -193,7 +193,7 @@ export async function getTokenExpiry(): Promise<number | null> {
try {
const store = await getStore();
if (store) {
const expiry = await store.get<number>(TOKEN_EXPIRY_KEY);
const expiry = (await store.get(TOKEN_EXPIRY_KEY)) as number | undefined;
return expiry || null;
}
} catch (error) {
Expand Down
5 changes: 3 additions & 2 deletions apps/web/src/utils/shareUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export {
import {
getPlatformShareUrl as getShareUrl,
PLATFORM_CONFIGS as platformConfigs,
type SharePlatform,
} from '@gruenerator/shared';

// Share content interface
Expand Down Expand Up @@ -198,7 +199,7 @@ const convertToPng = async (blob: Blob): Promise<Blob> => {
* Uses getPlatformShareUrl from shared package
*/
export const openPlatformShare = (platformId: string, text: string): boolean => {
const url = getShareUrl(platformId, text);
const url = getShareUrl(platformId as SharePlatform, text);
if (url) {
window.open(url, '_blank', 'width=600,height=400,noopener,noreferrer');
return true;
Expand All @@ -210,5 +211,5 @@ export const openPlatformShare = (platformId: string, text: string): boolean =>
* Check if a platform has a share URL
*/
export const hasPlatformShareUrl = (platformId: string): boolean => {
return platformConfigs[platformId]?.hasShareUrl === true;
return platformConfigs[platformId as SharePlatform]?.hasShareUrl === true;
};
Loading