eid-salami 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DEPLOY.md +199 -0
- package/README.md +133 -0
- package/backend/.env.example +25 -0
- package/backend/.keystone_temp/admin/next.config.js +14 -0
- package/backend/.keystone_temp/admin/pages/_app.js +22 -0
- package/backend/.keystone_temp/admin/pages/index.js +1 -0
- package/backend/.keystone_temp/admin/pages/init.js +5 -0
- package/backend/.keystone_temp/admin/pages/no-access.js +3 -0
- package/backend/.keystone_temp/admin/pages/orders/[id].js +3 -0
- package/backend/.keystone_temp/admin/pages/orders/create.js +3 -0
- package/backend/.keystone_temp/admin/pages/orders/index.js +3 -0
- package/backend/.keystone_temp/admin/pages/salami-packages/[id].js +3 -0
- package/backend/.keystone_temp/admin/pages/salami-packages/create.js +3 -0
- package/backend/.keystone_temp/admin/pages/salami-packages/index.js +3 -0
- package/backend/.keystone_temp/admin/pages/signin.js +3 -0
- package/backend/.keystone_temp/admin/pages/users/[id].js +3 -0
- package/backend/.keystone_temp/admin/pages/users/create.js +3 -0
- package/backend/.keystone_temp/admin/pages/users/index.js +3 -0
- package/backend/.keystone_temp/admin/public/favicon.ico +0 -0
- package/backend/.keystone_temp/config.js +369 -0
- package/backend/.keystone_temp/config.js.map +7 -0
- package/backend/bkash/bkash.service.ts +184 -0
- package/backend/keystone/routes.ts +193 -0
- package/backend/keystone/schema.ts +143 -0
- package/backend/keystone.ts +54 -0
- package/backend/package.json +23 -0
- package/backend/schema.graphql +530 -0
- package/backend/schema.prisma +55 -0
- package/backend/seed.ts +53 -0
- package/backend/tsconfig.json +15 -0
- package/frontend/.env.example +6 -0
- package/frontend/index.html +16 -0
- package/frontend/package.json +24 -0
- package/frontend/src/App.js +11 -0
- package/frontend/src/App.tsx +22 -0
- package/frontend/src/api/client.js +11 -0
- package/frontend/src/api/client.ts +57 -0
- package/frontend/src/components/Footer.js +5 -0
- package/frontend/src/components/Footer.module.css +27 -0
- package/frontend/src/components/Footer.tsx +13 -0
- package/frontend/src/components/Navbar.js +6 -0
- package/frontend/src/components/Navbar.module.css +54 -0
- package/frontend/src/components/Navbar.tsx +16 -0
- package/frontend/src/components/PackageCard.js +5 -0
- package/frontend/src/components/PackageCard.module.css +64 -0
- package/frontend/src/components/PackageCard.tsx +24 -0
- package/frontend/src/main.js +7 -0
- package/frontend/src/main.tsx +13 -0
- package/frontend/src/pages/HomePage.js +31 -0
- package/frontend/src/pages/HomePage.module.css +416 -0
- package/frontend/src/pages/HomePage.tsx +146 -0
- package/frontend/src/pages/OrderPage.js +98 -0
- package/frontend/src/pages/OrderPage.module.css +624 -0
- package/frontend/src/pages/OrderPage.tsx +221 -0
- package/frontend/src/pages/PaymentCallbackPage.js +25 -0
- package/frontend/src/pages/PaymentCallbackPage.module.css +38 -0
- package/frontend/src/pages/PaymentCallbackPage.tsx +37 -0
- package/frontend/src/pages/PaymentResultPage.js +28 -0
- package/frontend/src/pages/PaymentResultPage.module.css +182 -0
- package/frontend/src/pages/PaymentResultPage.tsx +92 -0
- package/frontend/src/styles/global.css +66 -0
- package/frontend/src/vite-env.d.ts +5 -0
- package/frontend/tsconfig.json +15 -0
- package/frontend/vite.config.ts +15 -0
- package/package.json +14 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Routes, Route } from 'react-router-dom'
|
|
2
|
+
import HomePage from './pages/HomePage'
|
|
3
|
+
import OrderPage from './pages/OrderPage'
|
|
4
|
+
import PaymentCallbackPage from './pages/PaymentCallbackPage'
|
|
5
|
+
import PaymentResultPage from './pages/PaymentResultPage'
|
|
6
|
+
import Navbar from './components/Navbar'
|
|
7
|
+
import Footer from './components/Footer'
|
|
8
|
+
|
|
9
|
+
export default function App() {
|
|
10
|
+
return (
|
|
11
|
+
<>
|
|
12
|
+
<Navbar />
|
|
13
|
+
<Routes>
|
|
14
|
+
<Route path="/" element={<HomePage />} />
|
|
15
|
+
<Route path="/send" element={<OrderPage />} />
|
|
16
|
+
<Route path="/payment/callback" element={<PaymentCallbackPage />} />
|
|
17
|
+
<Route path="/payment/result" element={<PaymentResultPage />} />
|
|
18
|
+
</Routes>
|
|
19
|
+
<Footer />
|
|
20
|
+
</>
|
|
21
|
+
)
|
|
22
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
const api = axios.create({
|
|
3
|
+
baseURL: import.meta.env.VITE_API_URL
|
|
4
|
+
? `${import.meta.env.VITE_API_URL}/api`
|
|
5
|
+
: '/api',
|
|
6
|
+
headers: { 'Content-Type': 'application/json' },
|
|
7
|
+
});
|
|
8
|
+
export const getPackages = () => api.get('/packages').then(r => r.data);
|
|
9
|
+
export const createOrder = (payload) => api.post('/orders/create', payload).then(r => r.data);
|
|
10
|
+
export const submitTrxID = (orderId, trxID) => api.post('/orders/submit-trxid', { orderId, trxID }).then(r => r.data);
|
|
11
|
+
export const getOrder = (id) => api.get(`/orders/${id}`).then(r => r.data);
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import axios from 'axios'
|
|
2
|
+
|
|
3
|
+
const api = axios.create({
|
|
4
|
+
baseURL: import.meta.env.VITE_API_URL
|
|
5
|
+
? `${import.meta.env.VITE_API_URL}/api`
|
|
6
|
+
: '/api',
|
|
7
|
+
headers: { 'Content-Type': 'application/json' },
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
export interface Package {
|
|
11
|
+
id: string
|
|
12
|
+
name: string
|
|
13
|
+
slug: string
|
|
14
|
+
amount: number
|
|
15
|
+
emoji: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface Order {
|
|
19
|
+
id: string
|
|
20
|
+
senderName: string
|
|
21
|
+
recipientName?: string
|
|
22
|
+
amount: number
|
|
23
|
+
senderMessage?: string
|
|
24
|
+
paymentStatus: 'pending' | 'pending_verification' | 'completed' | 'failed' | 'refunded'
|
|
25
|
+
deliveryStatus: 'waiting' | 'sent' | 'delivered'
|
|
26
|
+
bkashTrxID?: string
|
|
27
|
+
package: { name: string; amount: number; emoji: string }
|
|
28
|
+
createdAt: string
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface CreateOrderPayload {
|
|
32
|
+
senderName: string
|
|
33
|
+
senderPhone: string
|
|
34
|
+
senderMessage?: string
|
|
35
|
+
recipientName?: string
|
|
36
|
+
recipientPhone?: string
|
|
37
|
+
packageId: string
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface CreateOrderResult {
|
|
41
|
+
orderId: string
|
|
42
|
+
amount: number
|
|
43
|
+
bkashNumber: string
|
|
44
|
+
invoiceRef: string
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export const getPackages = () =>
|
|
48
|
+
api.get<Package[]>('/packages').then(r => r.data)
|
|
49
|
+
|
|
50
|
+
export const createOrder = (payload: CreateOrderPayload) =>
|
|
51
|
+
api.post<CreateOrderResult>('/orders/create', payload).then(r => r.data)
|
|
52
|
+
|
|
53
|
+
export const submitTrxID = (orderId: string, trxID: string) =>
|
|
54
|
+
api.post('/orders/submit-trxid', { orderId, trxID }).then(r => r.data)
|
|
55
|
+
|
|
56
|
+
export const getOrder = (id: string) =>
|
|
57
|
+
api.get<Order>(`/orders/${id}`).then(r => r.data)
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import styles from './Footer.module.css';
|
|
3
|
+
export default function Footer() {
|
|
4
|
+
return (_jsx("footer", { className: styles.footer, children: _jsxs("div", { className: styles.inner, children: [_jsx("p", { className: styles.bengali, children: "\u0988\u09A6 \u09AE\u09CB\u09AC\u09BE\u09B0\u0995 \uD83C\uDF19" }), _jsx("p", { className: styles.sub, children: "Made with love for Eid \u00B7 Powered by bKash" }), _jsxs("p", { className: styles.copy, children: ["\u00A9 ", new Date().getFullYear(), " Eid Salami. All rights reserved."] })] }) }));
|
|
5
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
.footer {
|
|
2
|
+
background: var(--emerald);
|
|
3
|
+
padding: 3rem clamp(1.5rem, 5vw, 4rem);
|
|
4
|
+
text-align: center;
|
|
5
|
+
border-top: 1px solid rgba(200, 153, 26, 0.25);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.inner { display: flex; flex-direction: column; gap: 0.4rem; }
|
|
9
|
+
|
|
10
|
+
.bengali {
|
|
11
|
+
font-family: var(--font-bengali);
|
|
12
|
+
font-size: 1.5rem;
|
|
13
|
+
color: var(--gold-bright);
|
|
14
|
+
font-weight: 700;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.sub {
|
|
18
|
+
font-size: 0.85rem;
|
|
19
|
+
color: rgba(245, 225, 160, 0.6);
|
|
20
|
+
font-weight: 300;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.copy {
|
|
24
|
+
font-size: 0.75rem;
|
|
25
|
+
color: rgba(255,255,255,0.3);
|
|
26
|
+
margin-top: 0.5rem;
|
|
27
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import styles from './Footer.module.css'
|
|
2
|
+
|
|
3
|
+
export default function Footer() {
|
|
4
|
+
return (
|
|
5
|
+
<footer className={styles.footer}>
|
|
6
|
+
<div className={styles.inner}>
|
|
7
|
+
<p className={styles.bengali}>ঈদ মোবারক 🌙</p>
|
|
8
|
+
<p className={styles.sub}>Made with love for Eid · Powered by bKash</p>
|
|
9
|
+
<p className={styles.copy}>© {new Date().getFullYear()} Eid Salami. All rights reserved.</p>
|
|
10
|
+
</div>
|
|
11
|
+
</footer>
|
|
12
|
+
)
|
|
13
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Link } from 'react-router-dom';
|
|
3
|
+
import styles from './Navbar.module.css';
|
|
4
|
+
export default function Navbar() {
|
|
5
|
+
return (_jsxs("nav", { className: styles.nav, children: [_jsxs(Link, { to: "/", className: styles.brand, children: [_jsx("span", { className: styles.moon, children: "\u263D" }), _jsx("span", { className: styles.title, children: "\u0988\u09A6 \u09B8\u09BE\u09B2\u09BE\u09AE\u09BF" })] }), _jsx(Link, { to: "/send", className: styles.cta, children: "\u09B8\u09BE\u09B2\u09BE\u09AE\u09BF \u09AA\u09BE\u09A0\u09BE\u09A8" })] }));
|
|
6
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
.nav {
|
|
2
|
+
position: sticky;
|
|
3
|
+
top: 0;
|
|
4
|
+
z-index: 100;
|
|
5
|
+
display: flex;
|
|
6
|
+
align-items: center;
|
|
7
|
+
justify-content: space-between;
|
|
8
|
+
padding: 0 clamp(1.5rem, 5vw, 4rem);
|
|
9
|
+
height: 68px;
|
|
10
|
+
background: rgba(13, 59, 46, 0.97);
|
|
11
|
+
backdrop-filter: blur(12px);
|
|
12
|
+
border-bottom: 1px solid rgba(200, 153, 26, 0.2);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.brand {
|
|
16
|
+
display: flex;
|
|
17
|
+
align-items: center;
|
|
18
|
+
gap: 0.6rem;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.moon {
|
|
22
|
+
font-size: 1.4rem;
|
|
23
|
+
color: var(--gold-bright);
|
|
24
|
+
animation: sway 4s ease-in-out infinite;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@keyframes sway {
|
|
28
|
+
0%, 100% { transform: rotate(-8deg); }
|
|
29
|
+
50% { transform: rotate(8deg); }
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.title {
|
|
33
|
+
font-family: var(--font-bengali);
|
|
34
|
+
font-size: 1.4rem;
|
|
35
|
+
font-weight: 700;
|
|
36
|
+
color: var(--gold-pale);
|
|
37
|
+
letter-spacing: 0.01em;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.cta {
|
|
41
|
+
font-family: var(--font-bengali);
|
|
42
|
+
font-size: 0.95rem;
|
|
43
|
+
font-weight: 600;
|
|
44
|
+
color: var(--emerald);
|
|
45
|
+
background: var(--gold-bright);
|
|
46
|
+
padding: 0.45rem 1.2rem;
|
|
47
|
+
border-radius: 100px;
|
|
48
|
+
transition: background 0.2s, transform 0.15s;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.cta:hover {
|
|
52
|
+
background: var(--gold-pale);
|
|
53
|
+
transform: translateY(-1px);
|
|
54
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Link } from 'react-router-dom'
|
|
2
|
+
import styles from './Navbar.module.css'
|
|
3
|
+
|
|
4
|
+
export default function Navbar() {
|
|
5
|
+
return (
|
|
6
|
+
<nav className={styles.nav}>
|
|
7
|
+
<Link to="/" className={styles.brand}>
|
|
8
|
+
<span className={styles.moon}>☽</span>
|
|
9
|
+
<span className={styles.title}>ঈদ সালামি</span>
|
|
10
|
+
</Link>
|
|
11
|
+
<Link to="/send" className={styles.cta}>
|
|
12
|
+
সালামি পাঠান
|
|
13
|
+
</Link>
|
|
14
|
+
</nav>
|
|
15
|
+
)
|
|
16
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import styles from './PackageCard.module.css';
|
|
3
|
+
export default function PackageCard({ pkg, selected, onSelect }) {
|
|
4
|
+
return (_jsxs("button", { className: `${styles.card} ${selected ? styles.selected : ''}`, onClick: () => onSelect(pkg.id), type: "button", "aria-pressed": selected, children: [_jsx("span", { className: styles.emoji, children: pkg.emoji }), _jsx("span", { className: styles.name, children: pkg.name }), _jsxs("span", { className: styles.amount, children: ["\u09F3", pkg.amount.toLocaleString('en-BD')] }), selected && _jsx("span", { className: styles.check, children: "\u2713" })] }));
|
|
5
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
.card {
|
|
2
|
+
position: relative;
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-direction: column;
|
|
5
|
+
align-items: center;
|
|
6
|
+
gap: 0.5rem;
|
|
7
|
+
padding: 1.5rem 1rem;
|
|
8
|
+
background: var(--white);
|
|
9
|
+
border: 2px solid transparent;
|
|
10
|
+
border-radius: var(--radius);
|
|
11
|
+
cursor: pointer;
|
|
12
|
+
transition: all 0.2s ease;
|
|
13
|
+
box-shadow: 0 2px 12px rgba(0,0,0,0.06);
|
|
14
|
+
min-width: 130px;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.card:hover {
|
|
18
|
+
border-color: var(--gold);
|
|
19
|
+
transform: translateY(-3px);
|
|
20
|
+
box-shadow: 0 8px 30px rgba(200, 153, 26, 0.2);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.selected {
|
|
24
|
+
border-color: var(--gold-bright) !important;
|
|
25
|
+
background: linear-gradient(135deg, #fffdf5 0%, #fff8e1 100%);
|
|
26
|
+
box-shadow: 0 8px 30px rgba(200, 153, 26, 0.25) !important;
|
|
27
|
+
transform: translateY(-3px);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.emoji {
|
|
31
|
+
font-size: 2rem;
|
|
32
|
+
line-height: 1;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.name {
|
|
36
|
+
font-family: var(--font-bengali);
|
|
37
|
+
font-size: 0.9rem;
|
|
38
|
+
font-weight: 600;
|
|
39
|
+
color: var(--emerald);
|
|
40
|
+
text-align: center;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.amount {
|
|
44
|
+
font-family: var(--font-display);
|
|
45
|
+
font-size: 1.3rem;
|
|
46
|
+
font-weight: 700;
|
|
47
|
+
color: var(--gold);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.check {
|
|
51
|
+
position: absolute;
|
|
52
|
+
top: 0.5rem;
|
|
53
|
+
right: 0.6rem;
|
|
54
|
+
font-size: 0.75rem;
|
|
55
|
+
color: var(--white);
|
|
56
|
+
background: var(--gold-bright);
|
|
57
|
+
width: 20px;
|
|
58
|
+
height: 20px;
|
|
59
|
+
border-radius: 50%;
|
|
60
|
+
display: flex;
|
|
61
|
+
align-items: center;
|
|
62
|
+
justify-content: center;
|
|
63
|
+
font-weight: 700;
|
|
64
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import styles from './PackageCard.module.css'
|
|
2
|
+
import type { Package } from '../api/client'
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
pkg: Package
|
|
6
|
+
selected: boolean
|
|
7
|
+
onSelect: (id: string) => void
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default function PackageCard({ pkg, selected, onSelect }: Props) {
|
|
11
|
+
return (
|
|
12
|
+
<button
|
|
13
|
+
className={`${styles.card} ${selected ? styles.selected : ''}`}
|
|
14
|
+
onClick={() => onSelect(pkg.id)}
|
|
15
|
+
type="button"
|
|
16
|
+
aria-pressed={selected}
|
|
17
|
+
>
|
|
18
|
+
<span className={styles.emoji}>{pkg.emoji}</span>
|
|
19
|
+
<span className={styles.name}>{pkg.name}</span>
|
|
20
|
+
<span className={styles.amount}>৳{pkg.amount.toLocaleString('en-BD')}</span>
|
|
21
|
+
{selected && <span className={styles.check}>✓</span>}
|
|
22
|
+
</button>
|
|
23
|
+
)
|
|
24
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import ReactDOM from 'react-dom/client';
|
|
4
|
+
import { BrowserRouter } from 'react-router-dom';
|
|
5
|
+
import App from './App';
|
|
6
|
+
import './styles/global.css';
|
|
7
|
+
ReactDOM.createRoot(document.getElementById('root')).render(_jsx(React.StrictMode, { children: _jsx(BrowserRouter, { children: _jsx(App, {}) }) }));
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import ReactDOM from 'react-dom/client'
|
|
3
|
+
import { BrowserRouter } from 'react-router-dom'
|
|
4
|
+
import App from './App'
|
|
5
|
+
import './styles/global.css'
|
|
6
|
+
|
|
7
|
+
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
8
|
+
<React.StrictMode>
|
|
9
|
+
<BrowserRouter>
|
|
10
|
+
<App />
|
|
11
|
+
</BrowserRouter>
|
|
12
|
+
</React.StrictMode>
|
|
13
|
+
)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { Link } from 'react-router-dom';
|
|
4
|
+
import { getPackages } from '../api/client';
|
|
5
|
+
import styles from './HomePage.module.css';
|
|
6
|
+
const STARS = Array.from({ length: 28 }, (_, i) => ({
|
|
7
|
+
id: i,
|
|
8
|
+
x: Math.random() * 100,
|
|
9
|
+
y: Math.random() * 60,
|
|
10
|
+
size: 2 + Math.random() * 3,
|
|
11
|
+
delay: Math.random() * 3,
|
|
12
|
+
}));
|
|
13
|
+
const STEPS = [
|
|
14
|
+
{ emoji: '🎁', title: 'প্যাকেজ বেছে নিন', sub: 'Choose a salami amount' },
|
|
15
|
+
{ emoji: '✍️', title: 'তথ্য পূরণ করুন', sub: 'Fill sender & recipient details' },
|
|
16
|
+
{ emoji: '💚', title: 'bKash-এ পেমেন্ট', sub: 'Pay securely via bKash' },
|
|
17
|
+
{ emoji: '🌙', title: 'সালামি পৌঁছে যাবে', sub: 'Salami delivered instantly' },
|
|
18
|
+
];
|
|
19
|
+
export default function HomePage() {
|
|
20
|
+
const [packages, setPackages] = useState([]);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
getPackages().then(setPackages).catch(() => { });
|
|
23
|
+
}, []);
|
|
24
|
+
return (_jsxs("main", { children: [_jsxs("section", { className: styles.hero, children: [_jsx("div", { className: styles.starfield, children: STARS.map(s => (_jsx("span", { className: styles.star, style: {
|
|
25
|
+
left: `${s.x}%`,
|
|
26
|
+
top: `${s.y}%`,
|
|
27
|
+
width: s.size,
|
|
28
|
+
height: s.size,
|
|
29
|
+
animationDelay: `${s.delay}s`,
|
|
30
|
+
} }, s.id))) }), _jsxs("div", { className: styles.heroContent, children: [_jsx("p", { className: styles.eyebrow, children: "\u0988\u09A6 \u09AE\u09CB\u09AC\u09BE\u09B0\u0995 \u2728" }), _jsxs("h1", { className: styles.heroTitle, children: ["Send Eid Salami", _jsx("br", {}), _jsx("em", { children: "with Love & Joy" })] }), _jsx("p", { className: styles.heroSub, children: "\u09AA\u09CD\u09B0\u09BF\u09AF\u09BC\u099C\u09A8\u0995\u09C7 \u0988\u09A6\u09C7\u09B0 \u09B8\u09BE\u09B2\u09BE\u09AE\u09BF \u09AA\u09BE\u09A0\u09BE\u09A8 \u2014 \u09B8\u09B9\u099C\u09C7, \u09A6\u09CD\u09B0\u09C1\u09A4, bKash-\u098F\u09B0 \u09AE\u09BE\u09A7\u09CD\u09AF\u09AE\u09C7\u0964" }), _jsxs("div", { className: styles.heroCtas, children: [_jsx(Link, { to: "/send", className: styles.btnPrimary, children: "\u098F\u0996\u09A8\u0987 \u09B8\u09BE\u09B2\u09BE\u09AE\u09BF \u09AA\u09BE\u09A0\u09BE\u09A8 \u2192" }), _jsx("a", { href: "#how", className: styles.btnGhost, children: "\u0995\u09C0\u09AD\u09BE\u09AC\u09C7 \u0995\u09BE\u099C \u0995\u09B0\u09C7?" })] }), _jsxs("div", { className: styles.heroStats, children: [_jsxs("div", { className: styles.stat, children: [_jsx("span", { className: styles.statNum, children: "\u09F3100" }), _jsx("span", { className: styles.statLabel, children: "\u09A5\u09C7\u0995\u09C7 \u09B6\u09C1\u09B0\u09C1" })] }), _jsx("div", { className: styles.statDivider }), _jsxs("div", { className: styles.stat, children: [_jsx("span", { className: styles.statNum, children: "bKash" }), _jsx("span", { className: styles.statLabel, children: "\u09AA\u09C7\u09AE\u09C7\u09A8\u09CD\u099F" })] }), _jsx("div", { className: styles.statDivider }), _jsxs("div", { className: styles.stat, children: [_jsx("span", { className: styles.statNum, children: "\u09A4\u09BE\u09CE\u0995\u09CD\u09B7\u09A3\u09BF\u0995" }), _jsx("span", { className: styles.statLabel, children: "\u09A1\u09C7\u09B2\u09BF\u09AD\u09BE\u09B0\u09BF" })] })] })] }), _jsxs("div", { className: styles.heroArt, children: [_jsx("div", { className: styles.moonRing, children: _jsx("div", { className: styles.moonInner, children: "\u263D" }) }), _jsx("div", { className: styles.lantern, children: "\uD83E\uDE94" }), _jsx("div", { className: styles.stars2, children: "\u2726 \u2726 \u2726" })] })] }), _jsx("section", { id: "how", className: styles.howSection, children: _jsxs("div", { className: styles.sectionInner, children: [_jsx("h2", { className: styles.sectionTitle, children: "\u0995\u09C0\u09AD\u09BE\u09AC\u09C7 \u0995\u09BE\u099C \u0995\u09B0\u09C7" }), _jsx("p", { className: styles.sectionSub, children: "\u09AE\u09BE\u09A4\u09CD\u09B0 \u09EA\u099F\u09BF \u09B8\u09B9\u099C \u09A7\u09BE\u09AA\u09C7 \u09B8\u09BE\u09B2\u09BE\u09AE\u09BF \u09AA\u09BE\u09A0\u09BE\u09A8" }), _jsx("div", { className: styles.steps, children: STEPS.map((step, i) => (_jsxs("div", { className: styles.step, children: [_jsx("div", { className: styles.stepNum, children: i + 1 }), _jsx("div", { className: styles.stepEmoji, children: step.emoji }), _jsx("h3", { className: styles.stepTitle, children: step.title }), _jsx("p", { className: styles.stepSub, children: step.sub })] }, i))) })] }) }), packages.length > 0 && (_jsx("section", { className: styles.packagesSection, children: _jsxs("div", { className: styles.sectionInner, children: [_jsx("h2", { className: styles.sectionTitle, children: "\u09B8\u09BE\u09B2\u09BE\u09AE\u09BF \u09AA\u09CD\u09AF\u09BE\u0995\u09C7\u099C" }), _jsx("p", { className: styles.sectionSub, children: "Choose the perfect amount for your loved one" }), _jsx("div", { className: styles.packagesGrid, children: packages.map(pkg => (_jsxs(Link, { to: `/send?package=${pkg.id}`, className: styles.pkgCard, children: [_jsx("span", { className: styles.pkgEmoji, children: pkg.emoji }), _jsx("span", { className: styles.pkgName, children: pkg.name }), _jsxs("span", { className: styles.pkgAmount, children: ["\u09F3", pkg.amount.toLocaleString()] }), _jsx("span", { className: styles.pkgBtn, children: "\u09AA\u09BE\u09A0\u09BE\u09A8 \u2192" })] }, pkg.id))) })] }) })), _jsx("section", { className: styles.ctaBanner, children: _jsxs("div", { className: styles.ctaInner, children: [_jsx("h2", { children: "\u0986\u099C\u0987 \u09B6\u09C1\u09B0\u09C1 \u0995\u09B0\u09C1\u09A8 \uD83C\uDF19" }), _jsx("p", { children: "\u0988\u09A6\u09C7\u09B0 \u0986\u09A8\u09A8\u09CD\u09A6 \u09AD\u09BE\u0997 \u0995\u09B0\u09C7 \u09A8\u09BF\u09A8 \u09AA\u09CD\u09B0\u09BF\u09AF\u09BC\u099C\u09A8\u09C7\u09B0 \u09B8\u09BE\u09A5\u09C7" }), _jsx(Link, { to: "/send", className: styles.btnPrimary, children: "\u09B8\u09BE\u09B2\u09BE\u09AE\u09BF \u09AA\u09BE\u09A0\u09BE\u09A8" })] }) })] }));
|
|
31
|
+
}
|