feat: preview click to section

This commit is contained in:
JOYCEQL
2024-12-24 18:37:30 +08:00
committed by qingchen
parent 8a728cca0a
commit 0122caa168
7 changed files with 47 additions and 30 deletions
@@ -52,26 +52,6 @@ export function EditorHeader({ isMobile }: EditorHeaderProps) {
<span className="text-lg font-semibold">Magic Resume</span>
<div className="w-2 h-2 rounded-full bg-indigo-500 animate-pulse" />
</motion.div>
{/* 在移动端隐藏导航按钮 */}
<div className="hidden md:flex items-center space-x-2">
{visibleSections?.map((section) => (
<motion.button
key={section.id}
className={`px-4 py-1.5 rounded-lg text-sm flex items-center space-x-2 shrink-0 ${
activeSection === section.id
? "bg-indigo-500/10 text-indigo-500"
: themeConfig.hover
}`}
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
onClick={() => setActiveSection(section.id)}
>
<span>{section.icon}</span>
<span>{section.title}</span>
</motion.button>
))}
</div>
</div>
<div className="flex items-center space-x-3">
@@ -8,6 +8,7 @@ import {
GlobalSettings,
} from "@/types/resume";
import { ResumeTemplate } from "@/types/template";
import { useResumeStore } from "@/store/useResumeStore";
interface BaseInfoProps {
basic: BasicInfo | undefined;
@@ -22,6 +23,7 @@ const BaseInfo = ({
layout,
template,
}: BaseInfoProps) => {
const { setActiveSection } = useResumeStore();
const useIconMode = globalSettings?.useIconMode ?? false;
const getIcon = (iconName: string | undefined) => {
@@ -271,11 +273,14 @@ const BaseInfo = ({
</div>
);
if (layout === "between") {
return BetweenContent;
}
const containerClass =
"hover:cursor-pointer hover:bg-gray-100 rounded-md transition-all duration-300 ease-in-out hover:shadow-md";
return CenterContent;
return (
<div className={containerClass} onClick={() => setActiveSection("basic")}>
{layout === "between" ? BetweenContent : CenterContent}
</div>
);
};
export default BaseInfo;
@@ -2,6 +2,7 @@
import { AnimatePresence, motion } from "framer-motion";
import SectionTitle from "./SectionTitle";
import { GlobalSettings, CustomItem } from "@/types/resume";
import { useResumeStore } from "@/store/useResumeStore";
interface CustomSectionProps {
sectionId: string;
@@ -11,20 +12,26 @@ interface CustomSectionProps {
}
const CustomSection = ({
sectionId,
title,
items,
globalSettings,
}: CustomSectionProps) => {
const { setActiveSection } = useResumeStore();
const visibleItems = items.filter((item) => {
return item.visible && (item.title || item.description);
});
return (
<motion.div
className="hover:cursor-pointer hover:bg-gray-100 rounded-md transition-all duration-300 ease-in-out hover:shadow-md"
layout
style={{
marginTop: `${globalSettings?.sectionSpacing || 24}px`,
}}
onClick={() => {
setActiveSection(sectionId);
}}
>
<SectionTitle
title={title}
@@ -2,6 +2,7 @@
import { AnimatePresence, motion } from "framer-motion";
import { Education, GlobalSettings } from "@/types/resume";
import SectionTitle from "./SectionTitle";
import { useResumeStore } from "@/store/useResumeStore";
interface EducationSectionProps {
education: Education[];
globalSettings: GlobalSettings | undefined;
@@ -11,12 +12,23 @@ const EducationSection = ({
education,
globalSettings,
}: EducationSectionProps) => {
const { setActiveSection } = useResumeStore();
const visibleEducation = education?.filter((edu) => edu.visible);
return (
<motion.div
className="hover:cursor-pointer
hover:bg-gray-100
rounded-md
transition-all
duration-300
ease-in-out
hover:shadow-md"
style={{
marginTop: `${globalSettings?.sectionSpacing || 24}px`,
}}
onClick={() => {
setActiveSection("education");
}}
>
<SectionTitle
type="education"
@@ -3,6 +3,7 @@ import React from "react";
import { motion, AnimatePresence } from "framer-motion";
import { Experience, GlobalSettings } from "@/types/resume";
import SectionTitle from "./SectionTitle";
import { useResumeStore } from "@/store/useResumeStore";
interface ExperienceSectionProps {
experiences?: Experience[];
@@ -50,18 +51,22 @@ const ExperienceSection: React.FC<ExperienceSectionProps> = ({
experiences,
globalSettings,
}) => {
if (!experiences?.length) return null;
const { setActiveSection } = useResumeStore();
const visibleExperiences = experiences.filter(
const visibleExperiences = experiences?.filter(
(experience) => experience.visible
);
return (
<motion.div
className="hover:cursor-pointer hover:bg-gray-100 rounded-md transition-all duration-300 ease-in-out hover:shadow-md"
layout
style={{
marginTop: `${globalSettings?.sectionSpacing || 24}px`,
}}
onClick={() => {
setActiveSection("experience");
}}
>
<SectionTitle type="experience" globalSettings={globalSettings} />
<div>
@@ -4,6 +4,7 @@ import React from "react";
import { motion, AnimatePresence } from "framer-motion";
import SectionTitle from "./SectionTitle";
import { Project, GlobalSettings } from "@/types/resume";
import { useResumeStore } from "@/store/useResumeStore";
interface ProjectItemProps {
project: Project;
@@ -57,16 +58,20 @@ const ProjectSection: React.FC<ProjectSectionProps> = ({
projects,
globalSettings,
}) => {
if (!projects?.length) return null;
const { setActiveSection } = useResumeStore();
const visibleProjects = projects.filter((project) => project.visible);
return (
<motion.div
className="hover:cursor-pointer hover:bg-gray-100 rounded-md transition-all duration-300 ease-in-out hover:shadow-md"
layout
style={{
marginTop: `${globalSettings?.sectionSpacing || 24}px`,
}}
onClick={() => {
setActiveSection("projects");
}}
>
<SectionTitle
type="projects"
@@ -2,6 +2,7 @@
import { motion } from "framer-motion";
import SectionTitle from "./SectionTitle";
import { GlobalSettings } from "@/types/resume";
import { useResumeStore } from "@/store/useResumeStore";
interface SkillSectionProps {
skill: string | undefined;
@@ -9,16 +10,18 @@ interface SkillSectionProps {
}
const SkillSection = ({ skill, globalSettings }: SkillSectionProps) => {
if (!skill) {
return null;
}
const { setActiveSection } = useResumeStore();
return (
<motion.div
layout
className="hover:cursor-pointer hover:bg-gray-100 rounded-md transition-all duration-300 ease-in-out hover:shadow-md"
style={{
marginTop: `${globalSettings?.sectionSpacing || 24}px`,
}}
onClick={() => {
setActiveSection("skills");
}}
>
<SectionTitle type="skills" globalSettings={globalSettings} />
<div