پروژه کامل: فرانت متصل به API + داکرایز

- اتصال کامل فرانت به API: همه محتوای سایت (پروژه‌ها، مقالات، خدمات، برند و...) از بک‌اند خوانده می‌شود (SiteProvider + useSite)
- فرم تماس و خبرنامه متصل به بک‌اند و تست‌شده در مرورگر
- ساختار مونوریپو: frontend/ + backend/
- Dockerfile برای هر دو بخش + docker-compose (PostgreSQL + FastAPI + nginx)
- nginx با پروکسی /api — بدون نیاز به CORS در حالت داکر
- README کامل فارسی
This commit is contained in:
Behrad
2026-08-29 13:26:58 +03:30
parent ed14435485
commit ad75f7a7bd
78 changed files with 8242 additions and 133 deletions
+93
View File
@@ -0,0 +1,93 @@
import React from 'react'
import { Link } from 'react-router-dom'
type Variant = 'copper' | 'outline' | 'dark' | 'dark-ivory'
type BaseProps = {
children: React.ReactNode
variant?: Variant
className?: string
}
const STYLES: Record<Variant, { base: string; fill: string; text: string }> = {
copper: {
base: 'bg-copper text-char',
fill: 'bg-char',
text: 'group-hover:text-ivory',
},
outline: {
base: 'border border-ivory/30 text-ivory',
fill: 'bg-copper',
text: 'group-hover:text-char',
},
dark: {
base: 'bg-char text-ivory',
fill: 'bg-copper',
text: 'group-hover:text-char',
},
'dark-ivory': {
base: 'bg-char text-ivory',
fill: 'bg-ivory',
text: 'group-hover:text-char',
},
}
function Inner({ children, variant = 'copper' }: { children: React.ReactNode; variant?: Variant }) {
const style = STYLES[variant]
return (
<>
<span
aria-hidden="true"
className={`absolute inset-0 translate-y-full transition-transform duration-[600ms] ease-lux group-hover:translate-y-0 ${style.fill}`}
/>
<span
className={`relative z-10 flex items-center justify-center gap-3 transition-colors duration-[600ms] ease-lux ${style.text}`}
>
{children}
</span>
</>
)
}
const SHELL =
'group relative inline-flex items-center justify-center overflow-hidden px-8 py-4 text-sm font-bold focus:outline-none focus-visible:ring-2 focus-visible:ring-copper focus-visible:ring-offset-2 focus-visible:ring-offset-ink'
export function ButtonLink({
to,
children,
variant = 'copper',
className = '',
}: BaseProps & { to: string }) {
return (
<Link to={to} className={`${SHELL} ${STYLES[variant].base} ${className}`}>
<Inner variant={variant}>{children}</Inner>
</Link>
)
}
export function ButtonAnchor({
href,
children,
variant = 'copper',
className = '',
...rest
}: BaseProps & { href: string } & React.AnchorHTMLAttributes<HTMLAnchorElement>) {
return (
<a href={href} className={`${SHELL} ${STYLES[variant].base} ${className}`} {...rest}>
<Inner variant={variant}>{children}</Inner>
</a>
)
}
export function Button({
children,
variant = 'copper',
className = '',
...rest
}: BaseProps & React.ButtonHTMLAttributes<HTMLButtonElement>) {
return (
<button className={`${SHELL} ${STYLES[variant].base} ${className}`} {...rest}>
<Inner variant={variant}>{children}</Inner>
</button>
)
}