2026-05-16 23:03:50 +00:00
|
|
|
package app
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"errors"
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
"archi_folio/internal/store"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func validateContent(c store.SiteContent) error {
|
|
|
|
|
switch {
|
|
|
|
|
case c.HeroTitle == "":
|
|
|
|
|
return errors.New("hero title is required")
|
|
|
|
|
case c.HeroSubtitle == "":
|
|
|
|
|
return errors.New("hero subtitle is required")
|
2026-05-17 12:36:50 +00:00
|
|
|
case c.Positioning == "":
|
|
|
|
|
return errors.New("positioning is required")
|
|
|
|
|
case c.HeroCTALabel == "" || c.HeroCTAURL == "":
|
|
|
|
|
return errors.New("primary hero CTA is required")
|
|
|
|
|
case c.SecondaryCTALabel == "" || c.SecondaryCTAURL == "":
|
|
|
|
|
return errors.New("secondary hero CTA is required")
|
2026-05-16 23:03:50 +00:00
|
|
|
case c.IntroTitle == "":
|
|
|
|
|
return errors.New("intro title is required")
|
|
|
|
|
case c.IntroText == "":
|
|
|
|
|
return errors.New("intro text is required")
|
2026-05-17 12:36:50 +00:00
|
|
|
case c.ServiceOneTitle == "" || c.ServiceOneText == "" || c.ServiceTwoTitle == "" || c.ServiceTwoText == "" || c.ServiceThreeTitle == "" || c.ServiceThreeText == "":
|
|
|
|
|
return errors.New("three service preview items are required")
|
|
|
|
|
case c.ProcessOneTitle == "" || c.ProcessOneText == "" || c.ProcessTwoTitle == "" || c.ProcessTwoText == "" || c.ProcessThreeTitle == "" || c.ProcessThreeText == "":
|
|
|
|
|
return errors.New("three process steps are required")
|
2026-05-16 23:03:50 +00:00
|
|
|
case c.AboutName == "":
|
|
|
|
|
return errors.New("about name is required")
|
|
|
|
|
case c.AboutRole == "":
|
|
|
|
|
return errors.New("about role is required")
|
|
|
|
|
case c.AboutBio == "":
|
|
|
|
|
return errors.New("about bio is required")
|
2026-05-17 12:36:50 +00:00
|
|
|
case c.StudioPhilosophy == "":
|
|
|
|
|
return errors.New("studio philosophy is required")
|
|
|
|
|
case c.StudioApproach == "":
|
|
|
|
|
return errors.New("studio approach is required")
|
|
|
|
|
case c.StudioCredentials == "":
|
|
|
|
|
return errors.New("studio credentials are required")
|
|
|
|
|
case c.ServiceArea == "":
|
|
|
|
|
return errors.New("service area is required")
|
2026-05-16 23:03:50 +00:00
|
|
|
case c.HeroImage == "":
|
|
|
|
|
return errors.New("hero image is required")
|
|
|
|
|
case c.AboutImage == "":
|
|
|
|
|
return errors.New("about image is required")
|
|
|
|
|
default:
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func validateContactDetails(c store.SiteContent) error {
|
|
|
|
|
switch {
|
|
|
|
|
case c.Email == "" || !strings.Contains(c.Email, "@"):
|
|
|
|
|
return errors.New("valid email is required")
|
|
|
|
|
case c.Phone == "":
|
|
|
|
|
return errors.New("phone is required")
|
|
|
|
|
case c.Location == "":
|
|
|
|
|
return errors.New("location is required")
|
|
|
|
|
default:
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-17 12:36:50 +00:00
|
|
|
func validateContactRequest(r store.ContactRequest) error {
|
|
|
|
|
switch {
|
|
|
|
|
case r.Name == "":
|
|
|
|
|
return errors.New("name is required")
|
|
|
|
|
case r.Email == "" || !strings.Contains(r.Email, "@"):
|
|
|
|
|
return errors.New("valid email is required")
|
|
|
|
|
case r.ProjectType == "":
|
|
|
|
|
return errors.New("project type is required")
|
|
|
|
|
case r.ProjectLocation == "":
|
|
|
|
|
return errors.New("project location is required")
|
|
|
|
|
case r.BudgetRange == "":
|
|
|
|
|
return errors.New("budget range is required")
|
|
|
|
|
case r.Timeline == "":
|
|
|
|
|
return errors.New("timeline is required")
|
|
|
|
|
case r.Message == "":
|
|
|
|
|
return errors.New("project message is required")
|
|
|
|
|
case len(r.Name) > 120:
|
|
|
|
|
return errors.New("name is too long")
|
|
|
|
|
case len(r.Email) > 180:
|
|
|
|
|
return errors.New("email is too long")
|
|
|
|
|
case len(r.Phone) > 80:
|
|
|
|
|
return errors.New("phone is too long")
|
|
|
|
|
case len(r.ProjectType) > 120:
|
|
|
|
|
return errors.New("project type is too long")
|
|
|
|
|
case len(r.ProjectLocation) > 180:
|
|
|
|
|
return errors.New("project location is too long")
|
|
|
|
|
case len(r.BudgetRange) > 120:
|
|
|
|
|
return errors.New("budget range is too long")
|
|
|
|
|
case len(r.Timeline) > 120:
|
|
|
|
|
return errors.New("timeline is too long")
|
|
|
|
|
case len(r.Message) > 3000:
|
|
|
|
|
return errors.New("project message is too long")
|
|
|
|
|
default:
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-16 23:03:50 +00:00
|
|
|
func validateProject(p store.Project) error {
|
|
|
|
|
switch {
|
|
|
|
|
case p.Slug == "":
|
|
|
|
|
return errors.New("project slug is required")
|
|
|
|
|
case p.Title == "":
|
|
|
|
|
return errors.New("project title is required")
|
|
|
|
|
case p.Location == "":
|
|
|
|
|
return errors.New("project location is required")
|
|
|
|
|
case p.Year == "":
|
|
|
|
|
return errors.New("project year is required")
|
|
|
|
|
case p.Category == "":
|
|
|
|
|
return errors.New("project category is required")
|
2026-05-17 12:36:50 +00:00
|
|
|
case p.Summary == "":
|
|
|
|
|
return errors.New("project summary is required")
|
|
|
|
|
case p.Scope == "":
|
|
|
|
|
return errors.New("project scope is required")
|
|
|
|
|
case p.Status == "":
|
|
|
|
|
return errors.New("project status is required")
|
2026-05-16 23:03:50 +00:00
|
|
|
case p.Description == "":
|
|
|
|
|
return errors.New("project description is required")
|
|
|
|
|
case p.CoverImage == "":
|
|
|
|
|
return errors.New("project cover image is required")
|
2026-05-17 12:36:50 +00:00
|
|
|
case len(p.Summary) > 500:
|
|
|
|
|
return errors.New("project summary is too long")
|
|
|
|
|
case len(p.Scope) > 240:
|
|
|
|
|
return errors.New("project scope is too long")
|
|
|
|
|
case len(p.Status) > 80:
|
|
|
|
|
return errors.New("project status is too long")
|
|
|
|
|
default:
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func validateService(service store.Service) error {
|
|
|
|
|
switch {
|
|
|
|
|
case service.Title == "":
|
|
|
|
|
return errors.New("service title is required")
|
|
|
|
|
case service.Summary == "":
|
|
|
|
|
return errors.New("service summary is required")
|
|
|
|
|
case service.Details == "":
|
|
|
|
|
return errors.New("service details are required")
|
|
|
|
|
case len(service.Title) > 160:
|
|
|
|
|
return errors.New("service title is too long")
|
|
|
|
|
case len(service.Summary) > 500:
|
|
|
|
|
return errors.New("service summary is too long")
|
|
|
|
|
case len(service.Details) > 2000:
|
|
|
|
|
return errors.New("service details are too long")
|
|
|
|
|
default:
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func validateFAQ(faq store.FAQ) error {
|
|
|
|
|
switch {
|
|
|
|
|
case faq.Question == "":
|
|
|
|
|
return errors.New("FAQ question is required")
|
|
|
|
|
case faq.Answer == "":
|
|
|
|
|
return errors.New("FAQ answer is required")
|
|
|
|
|
case len(faq.Question) > 240:
|
|
|
|
|
return errors.New("FAQ question is too long")
|
|
|
|
|
case len(faq.Answer) > 2000:
|
|
|
|
|
return errors.New("FAQ answer is too long")
|
2026-05-16 23:03:50 +00:00
|
|
|
default:
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
}
|