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
3 changes: 1 addition & 2 deletions apps/frontend/todo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@
},
"dependencies": {
"@packages/pb-api": "workspace:*",
"@packages/vds": "workspace:*",
"@radix-ui/react-dialog": "^1.1.4",
"@radix-ui/react-label": "^2.1.1",
"@radix-ui/react-slot": "^1.1.1",
"@radix-ui/react-toast": "^1.2.4",
"@radix-ui/react-checkbox": "^1.1.2",
"@shadcn/ui": "^0.0.4",
Expand Down
56 changes: 0 additions & 56 deletions apps/frontend/todo/src/components/ui/button.tsx

This file was deleted.

24 changes: 0 additions & 24 deletions apps/frontend/todo/src/components/ui/input.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion apps/frontend/todo/src/pages/goals/components/TodoItem.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import { Button } from '@packages/vds';
import { Todo } from '@/lib/types/';
import { TrashIcon } from 'lucide-react';
import React from 'react';
Expand Down
3 changes: 1 addition & 2 deletions apps/frontend/todo/src/pages/goals/components/TodoList.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Button, Input } from '@packages/vds';
import { Goal } from '@/lib/types/goal.type';
import { PlusIcon } from 'lucide-react';
import React from 'react';
Expand Down
3 changes: 1 addition & 2 deletions apps/frontend/todo/src/pages/goals/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Button, Input } from '@packages/vds';
import { PlusIcon } from 'lucide-react';
import React from 'react';
import GoalList from './components/GoalList';
Expand Down
2 changes: 1 addition & 1 deletion apps/frontend/todo/tailwind.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: ['class'],
content: ['./index.html', './src/**/*.{ts,tsx,js,jsx}'],
content: ['./index.html', './src/**/*.{ts,tsx,js,jsx}', '../../../packages/vds/src/**/*.{ts,tsx,js,jsx}'],
theme: {
extend: {
borderRadius: {
Expand Down
2 changes: 0 additions & 2 deletions apps/frontend/tool/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,8 @@
"@packages/api-client": "workspace:*",
"@packages/vds": "workspace:*",
"@radix-ui/react-dialog": "^1.1.4",
"@radix-ui/react-label": "^2.1.1",
"@radix-ui/react-progress": "^1.1.1",
"@radix-ui/react-radio-group": "^1.2.2",
"@radix-ui/react-slot": "^1.1.1",
"@radix-ui/react-toast": "^1.2.4",
"@shadcn/ui": "^0.0.4",
"class-variance-authority": "^0.7.1",
Expand Down
25 changes: 0 additions & 25 deletions apps/frontend/tool/src/components/common/ImagePreviewer.tsx

This file was deleted.

26 changes: 12 additions & 14 deletions apps/frontend/tool/src/components/common/ImageUploader.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
import React from 'react';

import { Input } from '@/components/ui/input';
import { Label } from '@packages/vds';
import { FileUploader, Label } from '@packages/vds';

interface ImageUploaderProps {
images: File[];
onUpload: (files: File[]) => void;
onRemove: (file: File) => void;
}

const ImageUploader = ({ onUpload }: ImageUploaderProps) => {
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
if (event.target.files) {
const files = Array.from(event.target.files);
onUpload(files);
}
};

const ImageUploader = ({ images, onUpload, onRemove }: ImageUploaderProps) => {
return (
<div className="grid w-full max-w-sm items-center gap-1.5">
<div className="grid w-full items-center gap-1.5 pb-4">
<Label htmlFor="image-file">{'이미지 파일을 업로드하세요.'}</Label>
<Input id="image-file" type="file" accept="image/*" multiple onChange={handleFileChange} />
<FileUploader
files={images}
onUpload={onUpload}
onRemove={onRemove}
className="w-full border border-gray-200 rounded-md p-2"
InputProps={{ accept: 'image/*', id: 'image-file' }}
/>
</div>
);
};
Expand Down
6 changes: 2 additions & 4 deletions apps/frontend/tool/src/components/common/VideoUploader.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react';

import { Input } from '@/components/ui/input';
import { Label } from '@packages/vds';
import { Label, FileInput } from '@packages/vds';

interface VideoUploaderProps {
file: File | null;
Expand All @@ -18,9 +17,8 @@ function VideoUploader({ file, onUpload }: VideoUploaderProps) {
return (
<div className="grid w-full max-w-sm items-center gap-1.5">
<Label htmlFor="video-file">{'비디오 파일을 업로드하세요.'}</Label>
<Input
<FileInput
id="video-file"
type="file"
accept="video/*"
onChange={handleFileChange}
name={file?.name}
Expand Down
23 changes: 0 additions & 23 deletions apps/frontend/tool/src/components/common/WrapImagePreview.tsx

This file was deleted.

26 changes: 18 additions & 8 deletions apps/frontend/tool/src/components/verticalMerger/ImageMerger.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,39 @@
import { useCallback, useRef, useState } from 'react';

import { Button } from '@packages/vds';
import { Label } from '@packages/vds';
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { Button, Label } from '@packages/vds';

const loadImage = (src: string): Promise<HTMLImageElement> => {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = reject;
img.src = src;
});
};

const alignOptions = ['left', 'center', 'right'] as const;

interface ImageMergerProps {
images: HTMLImageElement[];
files: File[];
onMergeComplete: (dataUrl: string) => void;
className?: string;
}

const ImageMerger = ({ images, onMergeComplete, className }: ImageMergerProps) => {
const ImageMerger = ({ files, onMergeComplete, className }: ImageMergerProps) => {
const canvasRef = useRef<HTMLCanvasElement>(null);
const [align, setAlign] = useState<(typeof alignOptions)[number]>('left');

const mergeImages = useCallback(() => {
if (!canvasRef.current || images.length === 0) return;
const mergeImages = useCallback(async () => {
if (!canvasRef.current || files.length === 0) return;

const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');

if (!ctx) return;

// Calculate canvas height
const images: HTMLImageElement[] = await Promise.all(files.map((file) => loadImage(URL.createObjectURL(file))));

const totalHeight = images.reduce((sum, img) => sum + img.height, 0);
const maxWidth = Math.max(...images.map((img) => img.width));

Expand All @@ -44,7 +54,7 @@ const ImageMerger = ({ images, onMergeComplete, className }: ImageMergerProps) =

const dataUrl = canvas.toDataURL('image/png');
onMergeComplete(dataUrl);
}, [align, images, onMergeComplete]);
}, [align, files, onMergeComplete]);

return (
<div className={className}>
Expand Down
3 changes: 1 addition & 2 deletions apps/frontend/tool/src/pages/GifGenerator.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { useCallback, useState } from 'react';

import DownloadButton from '@/components/common/DownloadButton';
import ImagePreviewer from '@/components/common/ImagePreviewer';
import PageTitle from '@/components/common/PageTitle';
import VideoUploader from '@/components/common/VideoUploader';
import VideoToGifControls from '@/components/gifGenerator/VideoToGifControls';

import { Button } from '@packages/vds';
import { useToast } from '@/hooks/use-toast';
import { Button, ImagePreviewer } from '@packages/vds';

function GifGenerator() {
const [videoFile, setVideoFile] = useState<File | null>(null);
Expand Down
31 changes: 7 additions & 24 deletions apps/frontend/tool/src/pages/VerticalImageMerger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ import { useCallback, useState } from 'react';
import DownloadButton from '@/components/common/DownloadButton';
import ImageUploader from '@/components/common/ImageUploader';
import PageTitle from '@/components/common/PageTitle';
import WrapImagePreview from '@/components/common/WrapImagePreview';
import ImageMerger from '@/components/verticalMerger/ImageMerger';
import MergedImagePreviewModal from '@/components/verticalMerger/MergedImagePreviewModal';
import { useToast } from '@/hooks/use-toast';
import { Button } from '@packages/vds';

function VerticalImageMerger() {
const [uploadedImages, setUploadedImages] = useState<HTMLImageElement[]>([]);
const [uploadedImages, setUploadedImages] = useState<File[]>([]);
const [mergedImage, setMergedImage] = useState<string>('');

const [openModal, setOpenModal] = useState(false);
Expand All @@ -28,38 +27,22 @@ function VerticalImageMerger() {
[toast],
);

const handleImageUpload = (files: File[], callback: (val: HTMLImageElement[]) => void) => {
const imageElements: HTMLImageElement[] = [];

files.forEach((file) => {
const reader = new FileReader();
reader.onload = (e) => {
const img = new Image();
img.src = e.target?.result as string;
img.onload = () => {
imageElements.push(img);
if (imageElements.length === files.length) {
callback(imageElements);
}
};
};
reader.readAsDataURL(file);
});
};

const handleReset = () => {
setUploadedImages([]);
setMergedImage('');
};

const handleRemove = (file: File) => {
setUploadedImages(uploadedImages.filter((i) => i !== file));
};

return (
<div>
<PageTitle>{'새로 이미지 병합기'}</PageTitle>
<ImageUploader onUpload={(files) => handleImageUpload(files, setUploadedImages)} />
<WrapImagePreview images={uploadedImages} />
<ImageUploader images={uploadedImages} onUpload={setUploadedImages} onRemove={handleRemove} />
{uploadedImages.length > 0 && <Button onClick={handleReset}>{'초기화'}</Button>}
{uploadedImages.length === 0 ? null : !mergedImage ? (
<ImageMerger className="text-center" images={uploadedImages} onMergeComplete={handleMergeComplete} />
<ImageMerger className="text-center" files={uploadedImages} onMergeComplete={handleMergeComplete} />
) : (
<p className="text-center">{'이미지 병합이 완료되었습니다. '}</p>
)}
Expand Down
2 changes: 1 addition & 1 deletion apps/frontend/tool/tailwind.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: ['class'],
content: ['./index.html', './src/**/*.{ts,tsx,js,jsx}'],
content: ['./index.html', './src/**/*.{ts,tsx,js,jsx}', '../../../packages/vds/src/**/*.{ts,tsx,js,jsx}'],
theme: {
extend: {
borderRadius: {
Expand Down
4 changes: 2 additions & 2 deletions packages/vds/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"scripts": {
"build": "pnpm rollup -c rollup.config.cjs --bundleConfigAsCjs",
"dev": "pnpm rollup -c rollup.config.cjs --bundleConfigAsCjs -w",
"build": "rm -rf dist && pnpm rollup -c rollup.config.cjs --bundleConfigAsCjs",
"dev": "rm -rf dist && pnpm rollup -c rollup.config.cjs --bundleConfigAsCjs -w",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
},
Expand Down
Loading
Loading