Reverted all changes back to version 90cfdf0785
This commit is contained in:
@@ -4,7 +4,6 @@ import "./globals.css";
|
||||
import { ThemeProvider } from "@/components/theme-provider";
|
||||
import { Toaster } from "@/components/ui/sonner";
|
||||
import { Footer } from "@/components/footer";
|
||||
import { I18nProvider } from "@/context/i18n-context";
|
||||
|
||||
const geistSans = Geist({
|
||||
variable: "--font-geist-sans",
|
||||
@@ -37,11 +36,9 @@ export default function RootLayout({
|
||||
enableSystem
|
||||
disableTransitionOnChange
|
||||
>
|
||||
<I18nProvider>
|
||||
{children}
|
||||
<Footer />
|
||||
<Toaster />
|
||||
</I18nProvider>
|
||||
</ThemeProvider>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
import { HomePage } from "@/components/home-page";
|
||||
import { ImageConverter } from "@/components/image-converter";
|
||||
|
||||
export default function Home() {
|
||||
return <HomePage />;
|
||||
return (
|
||||
<div className="relative flex flex-col items-center justify-center min-h-screen p-4 sm:p-8 bg-gray-50 dark:bg-background font-[family-name:var(--font-geist-sans)]">
|
||||
<main className="flex flex-col items-center w-full max-w-6xl z-10">
|
||||
<div className="text-center mb-8">
|
||||
<h1 className="text-4xl font-bold tracking-tight text-gray-900 dark:text-gray-100 sm:text-5xl">
|
||||
Image Web Exporter
|
||||
</h1>
|
||||
<p className="mt-3 text-lg text-gray-600 dark:text-gray-400">
|
||||
Upload a picture, then export it in a different resolution and format.
|
||||
</p>
|
||||
</div>
|
||||
<ImageConverter />
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -2,7 +2,6 @@ import Link from "next/link";
|
||||
import { Github, Twitter } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { changelogData } from "@/lib/changelog-data";
|
||||
import { LanguageSwitcher } from "./language-switcher";
|
||||
|
||||
export function Footer() {
|
||||
const latestVersion = changelogData[0]?.version;
|
||||
@@ -15,7 +14,6 @@ export function Footer() {
|
||||
</div>
|
||||
|
||||
<div className="absolute left-1/2 top-1/2 flex -translate-x-1/2 -translate-y-1/2 items-center gap-1">
|
||||
<LanguageSwitcher />
|
||||
<Button variant="ghost" size="icon" asChild>
|
||||
<Link href="https://github.com/" target="_blank" rel="noopener noreferrer" aria-label="GitHub">
|
||||
<Github className="h-4 w-4" />
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { ImageConverter } from "@/components/image-converter";
|
||||
import { useTranslation } from "@/context/i18n-context";
|
||||
|
||||
export function HomePage() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className="relative flex flex-col items-center justify-center min-h-screen p-4 sm:p-8 bg-gray-50 dark:bg-background font-[family-name:var(--font-geist-sans)]">
|
||||
<main className="flex flex-col items-center w-full max-w-6xl z-10">
|
||||
<div className="text-center mb-8">
|
||||
<h1 className="text-4xl font-bold tracking-tight text-gray-900 dark:text-gray-100 sm:text-5xl">
|
||||
{t('appTitle')}
|
||||
</h1>
|
||||
<p className="mt-3 text-lg text-gray-600 dark:text-gray-400">
|
||||
{t('appDescription')}
|
||||
</p>
|
||||
</div>
|
||||
<ImageConverter />
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -36,7 +36,6 @@ import {
|
||||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from "@/components/ui/tooltip";
|
||||
import { useTranslation } from "@/context/i18n-context";
|
||||
|
||||
const aspectRatios = [
|
||||
{ name: "Custom", value: "custom" },
|
||||
@@ -65,7 +64,6 @@ const initialSettings = {
|
||||
};
|
||||
|
||||
export function ImageConverter() {
|
||||
const { t } = useTranslation();
|
||||
const [images, setImages] = useState<File[]>([]);
|
||||
const [previewUrls, setPreviewUrls] = useState<string[]>([]);
|
||||
const [filenames, setFilenames] = useState<string[]>([]);
|
||||
@@ -429,7 +427,7 @@ export function ImageConverter() {
|
||||
<Card>
|
||||
<CardContent className="pt-6">
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-lg font-medium">{t('uploadTitle')}</h3>
|
||||
<h3 className="text-lg font-medium">Upload Images</h3>
|
||||
<div
|
||||
className={cn(
|
||||
"w-full h-48 rounded-lg border-2 border-dashed flex items-center justify-center relative transition-colors cursor-pointer hover:border-primary/60",
|
||||
@@ -442,8 +440,8 @@ export function ImageConverter() {
|
||||
>
|
||||
<div className="flex flex-col items-center justify-center text-center text-muted-foreground">
|
||||
<Upload className="w-8 h-8 mb-2" />
|
||||
<p className="font-semibold">{t('uploadPrompt')}</p>
|
||||
<p className="text-xs text-muted-foreground mt-1">{t('uploadFormats')}</p>
|
||||
<p className="font-semibold">Click or drag and drop to upload</p>
|
||||
<p className="text-xs text-muted-foreground mt-1">PNG, JPG, WEBP supported</p>
|
||||
</div>
|
||||
<Input type="file" ref={fileInputRef} onChange={handleImageChange} className="hidden" accept="image/*" multiple />
|
||||
</div>
|
||||
@@ -455,11 +453,11 @@ export function ImageConverter() {
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex justify-between items-center">
|
||||
<CardTitle>{t('uploadedImagesTitle')}</CardTitle>
|
||||
<CardTitle>Uploaded Images</CardTitle>
|
||||
<div className="flex items-center gap-2">
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button variant="ghost" size="sm" onClick={handleClearAll} disabled={isConverting || convertingIndex !== null}><Trash2 className="mr-2 h-4 w-4" />{t('clearAll')}</Button>
|
||||
<Button variant="ghost" size="sm" onClick={handleClearAll} disabled={isConverting || convertingIndex !== null}><Trash2 className="mr-2 h-4 w-4" />Clear All</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>Remove all uploaded images.</p>
|
||||
@@ -469,7 +467,7 @@ export function ImageConverter() {
|
||||
<TooltipTrigger asChild>
|
||||
<Button onClick={handleConvertAndDownloadAll} disabled={!hasImages || isConverting || convertingIndex !== null}>
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
{isConverting ? "Converting..." : t('downloadAll', { count: images.length })}
|
||||
{isConverting ? "Converting..." : `Download All (${images.length})`}
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { useTranslation } from "@/context/i18n-context";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { Languages } from "lucide-react";
|
||||
|
||||
export function LanguageSwitcher() {
|
||||
const { setLanguage } = useTranslation();
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" size="icon">
|
||||
<Languages className="h-4 w-4" />
|
||||
<span className="sr-only">Change language</span>
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuItem onClick={() => setLanguage("en")}>
|
||||
English
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => setLanguage("de")}>
|
||||
Deutsch
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
);
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import React, { createContext, useState, useContext, ReactNode } from 'react';
|
||||
import en from '@/locales/en.json';
|
||||
import de from '@/locales/de.json';
|
||||
|
||||
interface I18nContextType {
|
||||
language: string;
|
||||
setLanguage: (language: string) => void;
|
||||
t: (key: string, params?: { [key: string]: string | number }) => string;
|
||||
}
|
||||
|
||||
const I18nContext = createContext<I18nContextType | undefined>(undefined);
|
||||
|
||||
const translations: { [key: string]: { [key: string]: string } } = {
|
||||
en,
|
||||
de,
|
||||
};
|
||||
|
||||
export function I18nProvider({ children }: { children: ReactNode }) {
|
||||
const [language, setLanguage] = useState('en');
|
||||
|
||||
const t = (key: string, params?: { [key: string]: string | number }) => {
|
||||
let translation = translations[language]?.[key] || key;
|
||||
if (params) {
|
||||
Object.keys(params).forEach(paramKey => {
|
||||
translation = translation.replace(`{${paramKey}}`, String(params[paramKey]));
|
||||
});
|
||||
}
|
||||
return translation;
|
||||
};
|
||||
|
||||
return (
|
||||
<I18nContext.Provider value={{ language, setLanguage, t }}>
|
||||
{children}
|
||||
</I18nContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useTranslation() {
|
||||
const context = useContext(I18nContext);
|
||||
if (context === undefined) {
|
||||
throw new Error('useTranslation must be used within an I18nProvider');
|
||||
}
|
||||
return context;
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"appTitle": "Bild Web Exporter",
|
||||
"appDescription": "Laden Sie ein Bild hoch und exportieren Sie es in einer anderen Auflösung und einem anderen Format.",
|
||||
"uploadTitle": "Bilder hochladen",
|
||||
"uploadPrompt": "Klicken oder per Drag & Drop hochladen",
|
||||
"uploadFormats": "PNG, JPG, WEBP werden unterstützt",
|
||||
"uploadedImagesTitle": "Hochgeladene Bilder",
|
||||
"clearAll": "Alle löschen",
|
||||
"downloadAll": "Alle herunterladen ({count})"
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"appTitle": "Image Web Exporter",
|
||||
"appDescription": "Upload a picture, then export it in a different resolution and format.",
|
||||
"uploadTitle": "Upload Images",
|
||||
"uploadPrompt": "Click or drag and drop to upload",
|
||||
"uploadFormats": "PNG, JPG, WEBP supported",
|
||||
"uploadedImagesTitle": "Uploaded Images",
|
||||
"clearAll": "Clear All",
|
||||
"downloadAll": "Download All ({count})"
|
||||
}
|
||||
Reference in New Issue
Block a user