@restnfeel/agentc-starter-kit
Version:
한국어 기업용 CMS 모듈 - Task Master AI와 함께 빠르게 웹사이트를 구현할 수 있는 재사용 가능한 컴포넌트 시스템
243 lines (221 loc) • 7.27 kB
text/typescript
import { TemplateBase } from "../base-template";
import {
BaseTemplate,
BaseComponent,
ComponentType,
ServiceTier,
TemplateContext,
} from "../../../types/template-system";
/**
* Starter Tier Template Implementation
* 기본적인 웹사이트 구성 요소만 포함된 스타터 티어 템플릿
*/
export class StarterTemplate extends TemplateBase {
constructor(template: BaseTemplate) {
super(template);
// Starter tier validation
if (template.tier !== ServiceTier.STARTER) {
throw new Error(
"StarterTemplate can only be used with STARTER tier templates"
);
}
}
/**
* Starter tier에서 허용되는 컴포넌트 타입들
*/
private static readonly ALLOWED_COMPONENTS: ComponentType[] = [
ComponentType.HERO,
ComponentType.ABOUT,
ComponentType.CONTACT,
ComponentType.FOOTER,
];
/**
* 컴포넌트별 기본 props 생성
*/
protected createComponentProps(
component: BaseComponent,
context: TemplateContext
): Record<string, unknown> {
const baseProps = {
id: component.id,
className: `starter-${component.type.toLowerCase()}`,
theme: {
primaryColor: this.template.globalSettings.theme.primaryColor,
secondaryColor: this.template.globalSettings.theme.secondaryColor,
fontFamily: this.template.globalSettings.theme.fontFamily,
},
};
// 컴포넌트 타입별 특정 props 추가
switch (component.type) {
case ComponentType.HERO:
return {
...baseProps,
title: context.content.heroTitle || "환영합니다",
subtitle:
context.content.heroSubtitle ||
"귀하의 비즈니스를 위한 완벽한 솔루션을 제공합니다",
ctaText: context.content.heroCta || "시작하기",
ctaLink: "#contact",
backgroundImage: context.content.heroBackground,
};
case ComponentType.ABOUT:
return {
...baseProps,
title: context.content.aboutTitle || "회사 소개",
content:
context.content.aboutContent ||
"저희는 고객의 성공을 위해 최선을 다하는 전문적인 서비스를 제공합니다.",
image: context.content.aboutImage,
imageAlt: context.content.aboutImageAlt || "About us",
layout: context.content.aboutLayout || "right",
};
case ComponentType.CONTACT:
return {
...baseProps,
title: context.content.contactTitle || "연락처",
description:
context.content.contactDescription ||
"문의사항이 있으시면 언제든지 연락해 주세요.",
};
case ComponentType.FOOTER:
return {
...baseProps,
companyName: context.siteData.name,
description:
context.content.footerDescription ||
"비즈니스를 위한 완벽한 솔루션을 제공합니다.",
links: context.content.footerLinks || [
{ label: "서비스", href: "#services" },
{ label: "회사소개", href: "#about" },
{ label: "연락처", href: "#contact" },
],
socialLinks: context.content.socialLinks || [],
};
default:
return baseProps;
}
}
/**
* Starter tier에서 컴포넌트 추가 가능 여부 확인
*/
public override addComponent(component: BaseComponent): boolean {
// Starter tier에서 허용되지 않는 컴포넌트 체크
if (!StarterTemplate.ALLOWED_COMPONENTS.includes(component.type)) {
console.warn(
`Component type ${component.type} is not allowed in Starter tier. ` +
`Allowed components: ${StarterTemplate.ALLOWED_COMPONENTS.join(", ")}`
);
return false;
}
// 동일한 타입의 컴포넌트가 이미 있는지 체크 (Starter는 각 타입당 하나만 허용)
const existingComponent = this.getComponent(component.type);
if (existingComponent) {
console.warn(
`Component type ${component.type} already exists in Starter tier. ` +
`Only one component per type is allowed.`
);
return false;
}
return super.addComponent(component);
}
/**
* Starter tier 특정 검증 규칙
*/
public override validate(): { isValid: boolean; errors: string[] } {
const baseValidation = super.validate();
const errors: string[] = [...baseValidation.errors];
// Starter tier 특정 검증
const components = this.getActiveComponents();
// 필수 컴포넌트 체크
const requiredComponents = [ComponentType.HERO, ComponentType.FOOTER];
for (const requiredType of requiredComponents) {
const hasRequired = components.some((comp) => comp.type === requiredType);
if (!hasRequired) {
errors.push(`Missing required component: ${requiredType}`);
}
}
// 허용되지 않는 컴포넌트 체크
for (const component of components) {
if (!StarterTemplate.ALLOWED_COMPONENTS.includes(component.type)) {
errors.push(
`Component ${component.type} is not allowed in Starter tier`
);
}
}
// 컴포넌트 수 제한 (최대 4개)
if (components.length > 4) {
errors.push(
`Starter tier allows maximum 4 components, but ${components.length} were found`
);
}
return {
isValid: errors.length === 0,
errors,
};
}
/**
* Starter tier 업그레이드 경로 제공
*/
public getUpgradePath(): {
nextTier: ServiceTier;
newFeatures: string[];
additionalComponents: ComponentType[];
} {
return {
nextTier: ServiceTier.STANDARD,
newFeatures: [
"더 많은 컴포넌트 선택",
"고급 테마 커스터마이제이션",
"서비스 섹션",
"블로그 기능",
],
additionalComponents: [
ComponentType.SERVICES,
ComponentType.BLOG,
ComponentType.TESTIMONIALS,
],
};
}
/**
* Starter tier의 제한사항 정보 제공
*/
public getLimitations(): {
maxComponents: number;
allowedComponents: ComponentType[];
customizationLimits: string[];
} {
return {
maxComponents: 4,
allowedComponents: StarterTemplate.ALLOWED_COMPONENTS,
customizationLimits: [
"제한된 색상 팔레트",
"기본 글꼴만 사용 가능",
"기본 레이아웃만 지원",
"고급 커스터마이제이션 불가",
],
};
}
/**
* Starter tier 전용 컴포넌트 설정 업데이트
*/
public updateStarterSettings(settings: {
primaryColor?: string;
secondaryColor?: string;
fontFamily?: string;
companyName?: string;
}): void {
this.updateGlobalSettings({
theme: {
...this.template.globalSettings.theme,
primaryColor:
settings.primaryColor ||
this.template.globalSettings.theme.primaryColor,
secondaryColor:
settings.secondaryColor ||
this.template.globalSettings.theme.secondaryColor,
fontFamily:
settings.fontFamily || this.template.globalSettings.theme.fontFamily,
},
});
}
}