Skip to content

Commit

Permalink
design 2 finished
Browse files Browse the repository at this point in the history
  • Loading branch information
jongwony committed Nov 3, 2024
1 parent 8c2e9c7 commit 62fc423
Show file tree
Hide file tree
Showing 13 changed files with 481 additions and 1,082 deletions.
43 changes: 5 additions & 38 deletions src/app/Curation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import { useRouter } from 'next/navigation';
import styles from "./curation.module.css";

const templates = [
{ id: 'linkedin2', src: '/Linkedin2Light.png', alt: 'Linkedin2Light', path: '/form/linkedin2' },
{ id: 'insta_special', src: '/InstaSpecial.png', alt: 'InstaSpecial', path: '/form/insta_special' },
{ id: 'linkedin1', src: '/Linkedin1Dark.png', alt: 'Linkedin1Dark', path: '/form/linkedin1' },
{ id: 'insta1', src: '/Insta1Light.png', alt: 'Insta1Light', path: '/form/insta1' },
{ id: 'linkedin2', src: '/Linkedin2Light.png', alt: 'Linkedin2Light' },
{ id: 'insta_special', src: '/InstaSpecial.png', alt: 'InstaSpecial' },
{ id: 'linkedin1', src: '/Linkedin1Dark.png', alt: 'Linkedin1Dark' },
{ id: 'insta1', src: '/Insta1Light.png', alt: 'Insta1Light' },
];

export default function Curation() {
Expand All @@ -25,15 +25,6 @@ export default function Curation() {
return () => window.removeEventListener('resize', checkMobile);
}, []);

const navigateToPage = () => {
if (selectedTemplate) {
const template = templates.find(t => t.id === selectedTemplate);
if (template) {
router.push(template.path);
}
}
};

const handleImageInteraction = (id: string) => {
if (isMobile) {
setSelectedTemplate(prevSelected => prevSelected === id ? null : id);
Expand All @@ -49,7 +40,7 @@ export default function Curation() {
<div className="flex justify-center items-center">
<button
type="button"
onClick={() => router.push(templates[Math.floor(Math.random() * templates.length)].path)}
onClick={() => router.push('/form')}
className="px-4 py-2 text-white font-semibold bg-blue-500 rounded-md
hover:bg-blue-600 transition-colors"
>
Expand All @@ -74,19 +65,7 @@ export default function Curation() {
width={282}
height={568}
priority={true}
className={`transition-opacity duration-300 ${selectedTemplate === template.id ? 'opacity-50' : 'opacity-100'}`}
/>
{selectedTemplate === template.id && (
<button
type="button"
onClick={navigateToPage}
className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2
px-4 py-2 text-white font-semibold bg-blue-500 rounded-md
hover:bg-blue-600 transition-colors z-10"
>
만들기
</button>
)}
</div>
))}

Expand All @@ -103,19 +82,7 @@ export default function Curation() {
width={282}
height={568}
priority={true}
className={`transition-opacity duration-300 ${selectedTemplate === template.id ? 'opacity-50' : 'opacity-100'}`}
/>
{selectedTemplate === template.id && (
<button
type="button"
onClick={navigateToPage}
className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2
px-4 py-2 text-white font-semibold bg-blue-500 rounded-md
hover:bg-blue-600 transition-colors z-10"
>
만들기
</button>
)}
</div>
))}
</div>
Expand Down
43 changes: 0 additions & 43 deletions src/app/Template.tsx

This file was deleted.

9 changes: 6 additions & 3 deletions src/app/form/CropImage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Dispatch, SetStateAction, useEffect } from 'react';
import { useImageContext } from './ImageContext';
import Image from 'next/image'
import { X } from 'lucide-react';

type DisplayCroppedImageProps<T> = {
setFormData: Dispatch<SetStateAction<T>>;
Expand All @@ -17,9 +18,11 @@ export const DisplayCroppedImage = <T extends object>({ setFormData }: DisplayCr

return (
<div className="flex justify-center items-center w-full">
{croppedImage && (
<div>
<Image src={croppedImage} alt="Cropped" width={90} height={90} className="relative" />
{croppedImage ? (
<Image src={croppedImage} alt="Cropped" width={90} height={90} className="relative" />
) : (
<div className="w-20 h-20 mx-auto bg-zinc-800 rounded-full flex items-center justify-center">
<X className="w-8 h-8" />
</div>
)}
</div>
Expand Down
152 changes: 152 additions & 0 deletions src/app/form/Template.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
"use client"

import React, { useState, useEffect } from 'react'
import { motion, AnimatePresence } from "framer-motion"
import { ChevronLeft, ChevronRight } from "lucide-react"
import Image from "next/image"


interface TemplateProps {
templates: {id: string, name: string, path: string, src: string, dark: string, light: string}[];
initialTheme?: "light" | "dark";
onThemeChange: (theme: "light" | "dark") => void;
onTemplateChange: (template: string) => void;
}

export default function ChooseTemplate({ templates, initialTheme, onThemeChange, onTemplateChange }: TemplateProps) {
const [currentTemplate, setCurrentTemplate] = useState(0);
const [dragStart, setDragStart] = useState(0);
const [currentTheme, setCurrentTheme] = useState<"light" | "dark">(initialTheme || "dark");
const [direction, setDirection] = useState(1); // 방향 상태 유지

useEffect(() => {
onTemplateChange(templates[currentTemplate].id);
}, [currentTemplate]);

const handleThemeChange = (theme: "light" | "dark") => {
setCurrentTheme(theme)
onThemeChange(theme)
}

const handleNext = () => {
setDirection(1); // 다음으로 이동 시 방향을 1로 설정
setCurrentTemplate((prev) => {
const newIndex = (prev + 1) % templates.length;
onTemplateChange(templates[newIndex].id);
return newIndex;
})
}

const handlePrev = () => {
setDirection(-1); // 이전으로 이동 시 방향을 -1로 설정
setCurrentTemplate((prev) => {
const newIndex = (prev - 1 + templates.length) % templates.length;
onTemplateChange(templates[newIndex].id);
return newIndex;
})
}

const handleDragStart = (event: React.TouchEvent | React.MouseEvent) => {
const clientX = "touches" in event ? event.touches[0].clientX : event.clientX
setDragStart(clientX)
}

const handleDragEnd = (event: React.TouchEvent | React.MouseEvent) => {
const clientX = "changedTouches" in event ? event.changedTouches[0].clientX : event.clientX
const diff = dragStart - clientX

if (Math.abs(diff) > 50) {
if (diff > 0) {
handleNext()
} else {
handlePrev()
}
}
}

// Variants 정의
const variants = {
enter: (direction: number) => ({
x: direction * 300,
opacity: 0
}),
center: {
x: 0,
opacity: 1
},
exit: (direction: number) => ({
x: -direction * 300,
opacity: 0
})
};

return (
<div className="w-full max-w-md mx-auto space-y-8">
<div className="relative rounded-2xl bg-zinc-900">
<h1 className="text-2xl font-bold m-2 text-center">원하는 카드를 골라주세요</h1>
<p className="text-sm mb-6 text-gray-400 text-center">{templates[currentTemplate].name}</p>

<div
className="relative w-full flex justify-center items-center"
onTouchStart={handleDragStart}
onTouchEnd={handleDragEnd}
onMouseDown={handleDragStart}
onMouseUp={handleDragEnd}
>
<AnimatePresence custom={direction} mode="wait">
<motion.div
key={currentTemplate}
custom={direction}
variants={variants}
initial="enter"
animate="center"
exit="exit"
transition={{ type: "spring", stiffness: 300, damping: 30 }}
className="relative"
>
<Image
src={templates[currentTemplate].src !== '' ? templates[currentTemplate].src : (currentTheme === 'dark' ? templates[currentTemplate].dark : templates[currentTemplate].light)}
alt={templates[currentTemplate].name}
className={`aspect-[1/2] object-cover transition-colors duration-200`}
width={282}
height={568}
/>
</motion.div>
</AnimatePresence>
</div>
<button
type="button"
onClick={handlePrev}
className="absolute left-2 top-1/2 -translate-y-1/2 p-2 rounded-full bg-black/50 text-white hover:bg-black/70 transition-colors"
>
<ChevronLeft className="w-4 h-4" />
</button>
<button
type="button"
onClick={handleNext}
className="absolute right-2 top-1/2 -translate-y-1/2 p-2 rounded-full bg-black/50 text-white hover:bg-black/70 transition-colors"
>
<ChevronRight className="w-4 h-4" />
</button>
</div>

{(templates[currentTemplate].src === '') &&
<div className="flex justify-center items-center gap-4">
<button
type="button"
onClick={() => handleThemeChange("light")}
className={`w-8 h-8 rounded-full border-2 bg-white transition-all ${currentTheme === "light" ? "border-blue-500 scale-110" : "border-transparent"
}`}
aria-label="Light theme"
/>
<button
type="button"
onClick={() => handleThemeChange("dark")}
className={`w-8 h-8 rounded-full border-2 bg-black transition-all ${currentTheme === "dark" ? "border-blue-500 scale-110" : "border-transparent"
}`}
aria-label="Dark theme"
/>
</div>}
</div>
)
}
45 changes: 45 additions & 0 deletions src/app/form/Types.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
export interface Insta1Form {
template: string;
thumbnail?: string;
name?: string;
id?: string;
bio?: string;
code: string;
email: string;
theme?: "light" | "dark";
}

export interface InstaSpecialForm {
template: string;
thumbnail?: string;
name?: string;
id?: string;
bio?: string;
code: string;
email: string;
}

export interface Linkedin1Form {
template: string;
thumbnail?: string;
name?: string;
role?: string;
company?: string;
joinDate?: string;
code: string;
email: string;
theme?: "light" | "dark";
}

export interface Linkedin2Form {
template: string;
thumbnail?: string;
name?: string;
role?: string;
company?: string;
code: string;
email: string;
theme?: "light" | "dark";
}

export type FormDataTypes = Insta1Form | InstaSpecialForm | Linkedin1Form | Linkedin2Form;
Loading

0 comments on commit 62fc423

Please sign in to comment.