before race
This commit is contained in:
146
Requirements.md
Normal file
146
Requirements.md
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
420Deals.ch – Project Brief (for Dev)
|
||||||
|
|
||||||
|
Core idea:
|
||||||
|
420Deals.ch is NOT a normal shop.
|
||||||
|
It’s a collective drop system.
|
||||||
|
|
||||||
|
There is always only ONE active product drop.
|
||||||
|
Each drop has a fixed total batch (e.g. 1kg).
|
||||||
|
Users buy parts of the batch (50g / 100g / 250g).
|
||||||
|
Everyone pays the same wholesale price per gram.
|
||||||
|
When the batch is fully sold → the drop ends automatically.
|
||||||
|
Only after that, the next drop goes live.
|
||||||
|
|
||||||
|
Value proposition:
|
||||||
|
Wholesale prices for private buyers through collective purchasing.
|
||||||
|
No retail packaging. No marketing markup.
|
||||||
|
|
||||||
|
Page structure:
|
||||||
|
Everything happens on ONE page.
|
||||||
|
|
||||||
|
Navigation (sticky):
|
||||||
|
|
||||||
|
Drop
|
||||||
|
|
||||||
|
Past Drops
|
||||||
|
|
||||||
|
Community
|
||||||
|
|
||||||
|
Header:
|
||||||
|
Text only.
|
||||||
|
Explains why prices are low.
|
||||||
|
No big images, no CTA.
|
||||||
|
User attention goes directly to the active drop.
|
||||||
|
|
||||||
|
Current Drop section:
|
||||||
|
|
||||||
|
Product image
|
||||||
|
|
||||||
|
Product name + batch info (e.g. 1kg, indoor, Switzerland)
|
||||||
|
|
||||||
|
Price per gram (incl. 2.5% VAT)
|
||||||
|
|
||||||
|
Live progress bar (how much of the batch is sold)
|
||||||
|
|
||||||
|
Quantity selection (50g / 100g / 250g)
|
||||||
|
|
||||||
|
CTA: “Join the Drop”
|
||||||
|
|
||||||
|
Important:
|
||||||
|
Same price for everyone.
|
||||||
|
No discounts, no codes.
|
||||||
|
The advantage comes only from collective volume.
|
||||||
|
|
||||||
|
Progress bar logic:
|
||||||
|
Example:
|
||||||
|
Total batch: 1000g
|
||||||
|
Sold: 620g
|
||||||
|
Progress: 62%
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
Transparency, trust, FOMO.
|
||||||
|
|
||||||
|
Auto-Switch Drop (important):
|
||||||
|
When soldGrams >= totalBatch:
|
||||||
|
|
||||||
|
Replace the entire drop section with:
|
||||||
|
“Drop sold out”
|
||||||
|
“Next collective drop coming soon”
|
||||||
|
|
||||||
|
Countdown timer
|
||||||
|
|
||||||
|
Users cannot buy anymore, only wait or subscribe.
|
||||||
|
|
||||||
|
Countdown:
|
||||||
|
Countdown shows days / hours / minutes to next drop.
|
||||||
|
When countdown ends → next drop can go live.
|
||||||
|
|
||||||
|
Why it’s cheap section:
|
||||||
|
Short explanation:
|
||||||
|
Retail ~10 CHF/g
|
||||||
|
Collective ~2.5 CHF/g
|
||||||
|
No retail packaging
|
||||||
|
No tobacco tax
|
||||||
|
No intermediaries
|
||||||
|
|
||||||
|
Tone: factual, clean, Swiss-style.
|
||||||
|
|
||||||
|
Community / Notifications:
|
||||||
|
Purpose: users don’t need to check the site daily.
|
||||||
|
|
||||||
|
Fields:
|
||||||
|
|
||||||
|
Email
|
||||||
|
|
||||||
|
WhatsApp number
|
||||||
|
|
||||||
|
Optional later:
|
||||||
|
Telegram broadcast (one-way only, no public chat).
|
||||||
|
|
||||||
|
No community chat on site → keeps it premium and controlled.
|
||||||
|
|
||||||
|
Past Drops:
|
||||||
|
Show previous drops:
|
||||||
|
|
||||||
|
Product name
|
||||||
|
|
||||||
|
“Sold out in XX hours”
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
Trust, credibility, FOMO.
|
||||||
|
|
||||||
|
Position:
|
||||||
|
After current drop, before footer.
|
||||||
|
|
||||||
|
Footer:
|
||||||
|
|
||||||
|
THC < 1%
|
||||||
|
|
||||||
|
18+ only
|
||||||
|
|
||||||
|
Switzerland
|
||||||
|
|
||||||
|
Minimal text
|
||||||
|
|
||||||
|
Technical notes:
|
||||||
|
Frontend:
|
||||||
|
Dark theme, no emojis, no flashy colors.
|
||||||
|
Focus on typography and spacing.
|
||||||
|
|
||||||
|
Backend:
|
||||||
|
Drop object:
|
||||||
|
|
||||||
|
Name
|
||||||
|
|
||||||
|
Total batch size
|
||||||
|
|
||||||
|
Sold amount
|
||||||
|
|
||||||
|
Start / end date
|
||||||
|
Progress bar updates dynamically.
|
||||||
|
Auto-switch when sold out.
|
||||||
|
Countdown configurable.
|
||||||
|
|
||||||
|
Summary:
|
||||||
|
420Deals.ch is not a shop, not a forum, not a headshop.
|
||||||
|
It’s a premium collective buying platform for CBD in Switzerland.
|
||||||
@@ -419,8 +419,8 @@ export default function Drop() {
|
|||||||
disabled={processing}
|
disabled={processing}
|
||||||
style={{
|
style={{
|
||||||
padding: '12px 24px',
|
padding: '12px 24px',
|
||||||
background: 'var(--accent)',
|
background: '#0a7931',
|
||||||
color: '#000',
|
color: '#fff',
|
||||||
border: 'none',
|
border: 'none',
|
||||||
borderRadius: '14px',
|
borderRadius: '14px',
|
||||||
cursor: processing ? 'not-allowed' : 'pointer',
|
cursor: processing ? 'not-allowed' : 'pointer',
|
||||||
|
|||||||
@@ -54,7 +54,11 @@ export default function Nav() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<nav>
|
<nav>
|
||||||
<div className="brand">420Deals.ch</div>
|
<div className="brand">
|
||||||
|
<a href="/" style={{ display: 'inline-block', textDecoration: 'none' }}>
|
||||||
|
<img src="/header.jpg" alt="420Deals.ch" style={{ height: '40px', width: 'auto' }} />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
<div className="links">
|
<div className="links">
|
||||||
<a href="#drop">Drop</a>
|
<a href="#drop">Drop</a>
|
||||||
<a href="#past">Past Drops</a>
|
<a href="#past">Past Drops</a>
|
||||||
@@ -90,8 +94,8 @@ export default function Nav() {
|
|||||||
style={{
|
style={{
|
||||||
padding: '8px 16px',
|
padding: '8px 16px',
|
||||||
fontSize: '14px',
|
fontSize: '14px',
|
||||||
background: 'var(--accent)',
|
background: '#0a7931',
|
||||||
color: '#000',
|
color: '#fff',
|
||||||
border: 'none',
|
border: 'none',
|
||||||
borderRadius: '8px',
|
borderRadius: '8px',
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
|
|||||||
@@ -15,7 +15,12 @@ interface PastDrop {
|
|||||||
soldOutInHours: number
|
soldOutInHours: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function PastDrops() {
|
interface PastDropsProps {
|
||||||
|
limit?: number
|
||||||
|
showMoreLink?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function PastDrops({ limit, showMoreLink = false }: PastDropsProps = {}) {
|
||||||
const [drops, setDrops] = useState<PastDrop[]>([])
|
const [drops, setDrops] = useState<PastDrop[]>([])
|
||||||
const [loading, setLoading] = useState(true)
|
const [loading, setLoading] = useState(true)
|
||||||
|
|
||||||
@@ -55,6 +60,20 @@ export default function PastDrops() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const formatDateAndTime = (dateString: string) => {
|
||||||
|
const date = new Date(dateString)
|
||||||
|
const day = date.getDate()
|
||||||
|
const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
|
||||||
|
const month = monthNames[date.getMonth()]
|
||||||
|
const hours = date.getHours().toString().padStart(2, '0')
|
||||||
|
const minutes = date.getMinutes().toString().padStart(2, '0')
|
||||||
|
return `${day} ${month} · ${hours}:${minutes}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatQuantity = (size: number, unit: string) => {
|
||||||
|
return `${size}${unit}`
|
||||||
|
}
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return (
|
return (
|
||||||
<div className="past">
|
<div className="past">
|
||||||
@@ -73,50 +92,72 @@ export default function PastDrops() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const displayedDrops = limit ? drops.slice(0, limit) : drops
|
||||||
|
const hasMore = limit && drops.length > limit
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="past">
|
<>
|
||||||
{drops.map((drop) => (
|
<div className="past">
|
||||||
<div key={drop.id} className="card">
|
{displayedDrops.map((drop) => (
|
||||||
{drop.image_url ? (
|
<div key={drop.id} className="card">
|
||||||
<div style={{ marginBottom: '12px' }}>
|
{drop.image_url ? (
|
||||||
<Image
|
<div style={{ marginBottom: '12px' }}>
|
||||||
src={drop.image_url}
|
<Image
|
||||||
alt={drop.item}
|
src={drop.image_url}
|
||||||
width={300}
|
alt={drop.item}
|
||||||
height={300}
|
width={300}
|
||||||
|
height={300}
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
height: '200px',
|
||||||
|
borderRadius: '12px',
|
||||||
|
objectFit: 'cover',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div
|
||||||
style={{
|
style={{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
maxWidth: '300px',
|
height: '200px',
|
||||||
height: '300px',
|
background: 'var(--bg-soft)',
|
||||||
borderRadius: '12px',
|
borderRadius: '12px',
|
||||||
objectFit: 'cover',
|
marginBottom: '12px',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
color: 'var(--muted)',
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
</div>
|
No Image
|
||||||
) : (
|
</div>
|
||||||
<div
|
)}
|
||||||
style={{
|
<strong>{drop.item}</strong>
|
||||||
width: '100%',
|
<br />
|
||||||
maxWidth: '300px',
|
<span className="meta">{formatSoldOutTime(drop.soldOutInHours)}</span>
|
||||||
height: '300px',
|
<br />
|
||||||
background: 'var(--bg-soft)',
|
<span className="meta" style={{ fontSize: '13px', marginTop: '4px', display: 'block' }}>
|
||||||
borderRadius: '12px',
|
{formatQuantity(drop.size, drop.unit)} · {formatDateAndTime(drop.created_at)}
|
||||||
marginBottom: '12px',
|
</span>
|
||||||
display: 'flex',
|
</div>
|
||||||
alignItems: 'center',
|
))}
|
||||||
justifyContent: 'center',
|
</div>
|
||||||
color: 'var(--muted)',
|
{showMoreLink && hasMore && (
|
||||||
}}
|
<div style={{ textAlign: 'center', marginTop: '30px' }}>
|
||||||
>
|
<a
|
||||||
No Image
|
href="/past-drops"
|
||||||
</div>
|
style={{
|
||||||
)}
|
color: 'var(--accent)',
|
||||||
<strong>{drop.item}</strong>
|
textDecoration: 'none',
|
||||||
<br />
|
fontSize: '14px',
|
||||||
<span className="meta">{formatSoldOutTime(drop.soldOutInHours)}</span>
|
fontWeight: 500,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
More →
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
))}
|
)}
|
||||||
</div>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -146,8 +146,8 @@ header p {
|
|||||||
.cta {
|
.cta {
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
padding: 16px 28px;
|
padding: 16px 28px;
|
||||||
background: var(--accent);
|
background: #0a7931;
|
||||||
color: #000;
|
color: #fff;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 14px;
|
border-radius: 14px;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
@@ -197,8 +197,8 @@ header p {
|
|||||||
.signup button {
|
.signup button {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
padding: 14px 28px;
|
padding: 14px 28px;
|
||||||
background: var(--accent);
|
background: #0a7931;
|
||||||
color: #000;
|
color: #fff;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 14px;
|
border-radius: 14px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@@ -206,9 +206,9 @@ header p {
|
|||||||
|
|
||||||
.past {
|
.past {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(400px, 400px));
|
grid-template-columns: repeat(3, 1fr);
|
||||||
gap: 30px;
|
gap: 20px;
|
||||||
justify-content: center;
|
justify-content: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.past .card {
|
.past .card {
|
||||||
@@ -216,7 +216,7 @@ header p {
|
|||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
width: 400px;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.past img {
|
.past img {
|
||||||
@@ -237,6 +237,16 @@ footer {
|
|||||||
.drop {
|
.drop {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.past {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.past {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Admin Panel Styles */
|
/* Admin Panel Styles */
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ export default function Home() {
|
|||||||
|
|
||||||
<section className="container" id="past">
|
<section className="container" id="past">
|
||||||
<h2>Past Drops</h2>
|
<h2>Past Drops</h2>
|
||||||
<PastDrops />
|
<PastDrops limit={3} showMoreLink={true} />
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<Footer />
|
<Footer />
|
||||||
|
|||||||
39
app/past-drops/page.tsx
Normal file
39
app/past-drops/page.tsx
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import Nav from '../components/Nav'
|
||||||
|
import PastDrops from '../components/PastDrops'
|
||||||
|
import Footer from '../components/Footer'
|
||||||
|
|
||||||
|
export default function PastDropsPage() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Nav />
|
||||||
|
<section className="container" style={{ paddingTop: '120px' }}>
|
||||||
|
<a
|
||||||
|
href="/"
|
||||||
|
style={{
|
||||||
|
display: 'inline-flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
color: 'var(--muted)',
|
||||||
|
textDecoration: 'none',
|
||||||
|
fontSize: '14px',
|
||||||
|
marginBottom: '30px',
|
||||||
|
transition: 'color 0.2s',
|
||||||
|
}}
|
||||||
|
onMouseEnter={(e) => {
|
||||||
|
e.currentTarget.style.color = 'var(--text)'
|
||||||
|
}}
|
||||||
|
onMouseLeave={(e) => {
|
||||||
|
e.currentTarget.style.color = 'var(--muted)'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
← Back
|
||||||
|
</a>
|
||||||
|
<h1 style={{ marginBottom: '40px' }}>Past Drops</h1>
|
||||||
|
<PastDrops />
|
||||||
|
</section>
|
||||||
|
<Footer />
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
49
cbd420.sql
49
cbd420.sql
@@ -3,7 +3,7 @@
|
|||||||
-- https://www.phpmyadmin.net/
|
-- https://www.phpmyadmin.net/
|
||||||
--
|
--
|
||||||
-- Host: localhost:3306
|
-- Host: localhost:3306
|
||||||
-- Generation Time: Dec 20, 2025 at 04:42 AM
|
-- Generation Time: Dec 21, 2025 at 06:50 AM
|
||||||
-- Server version: 10.11.14-MariaDB-0+deb12u2
|
-- Server version: 10.11.14-MariaDB-0+deb12u2
|
||||||
-- PHP Version: 8.2.29
|
-- PHP Version: 8.2.29
|
||||||
|
|
||||||
@@ -31,7 +31,8 @@ CREATE TABLE `buyers` (
|
|||||||
`id` int(11) NOT NULL,
|
`id` int(11) NOT NULL,
|
||||||
`username` varchar(255) NOT NULL,
|
`username` varchar(255) NOT NULL,
|
||||||
`password` varchar(255) NOT NULL,
|
`password` varchar(255) NOT NULL,
|
||||||
`email` varchar(255) NOT NULL
|
`email` varchar(255) NOT NULL,
|
||||||
|
`created_at` datetime NOT NULL DEFAULT current_timestamp()
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||||
|
|
||||||
-- --------------------------------------------------------
|
-- --------------------------------------------------------
|
||||||
@@ -59,7 +60,27 @@ CREATE TABLE `drops` (
|
|||||||
`size` int(11) NOT NULL DEFAULT 100,
|
`size` int(11) NOT NULL DEFAULT 100,
|
||||||
`fill` int(11) NOT NULL DEFAULT 0,
|
`fill` int(11) NOT NULL DEFAULT 0,
|
||||||
`unit` varchar(12) NOT NULL DEFAULT 'g',
|
`unit` varchar(12) NOT NULL DEFAULT 'g',
|
||||||
|
`image_url` varchar(255) DEFAULT NULL,
|
||||||
`ppu` int(11) NOT NULL DEFAULT 1,
|
`ppu` int(11) NOT NULL DEFAULT 1,
|
||||||
|
`created_at` datetime NOT NULL DEFAULT current_timestamp(),
|
||||||
|
`start_time` datetime DEFAULT NULL
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||||
|
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `pending_orders`
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE `pending_orders` (
|
||||||
|
`id` int(11) NOT NULL,
|
||||||
|
`payment_id` varchar(255) NOT NULL,
|
||||||
|
`order_id` varchar(255) NOT NULL,
|
||||||
|
`drop_id` int(11) NOT NULL,
|
||||||
|
`buyer_id` int(11) NOT NULL,
|
||||||
|
`size` int(11) NOT NULL,
|
||||||
|
`price_amount` decimal(10,2) NOT NULL,
|
||||||
|
`price_currency` varchar(10) NOT NULL DEFAULT 'chf',
|
||||||
`created_at` datetime NOT NULL DEFAULT current_timestamp()
|
`created_at` datetime NOT NULL DEFAULT current_timestamp()
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||||
|
|
||||||
@@ -74,6 +95,7 @@ CREATE TABLE `sales` (
|
|||||||
`drop_id` int(11) NOT NULL,
|
`drop_id` int(11) NOT NULL,
|
||||||
`buyer_id` int(11) NOT NULL,
|
`buyer_id` int(11) NOT NULL,
|
||||||
`size` int(11) NOT NULL DEFAULT 1,
|
`size` int(11) NOT NULL DEFAULT 1,
|
||||||
|
`payment_id` text NOT NULL DEFAULT '',
|
||||||
`created_at` datetime NOT NULL DEFAULT current_timestamp()
|
`created_at` datetime NOT NULL DEFAULT current_timestamp()
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||||
|
|
||||||
@@ -100,6 +122,16 @@ ALTER TABLE `deliveries`
|
|||||||
ALTER TABLE `drops`
|
ALTER TABLE `drops`
|
||||||
ADD PRIMARY KEY (`id`);
|
ADD PRIMARY KEY (`id`);
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Indexes for table `pending_orders`
|
||||||
|
--
|
||||||
|
ALTER TABLE `pending_orders`
|
||||||
|
ADD PRIMARY KEY (`id`),
|
||||||
|
ADD UNIQUE KEY `payment_id` (`payment_id`),
|
||||||
|
ADD UNIQUE KEY `order_id` (`order_id`),
|
||||||
|
ADD KEY `drop_id` (`drop_id`),
|
||||||
|
ADD KEY `buyer_id` (`buyer_id`);
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Indexes for table `sales`
|
-- Indexes for table `sales`
|
||||||
--
|
--
|
||||||
@@ -130,6 +162,12 @@ ALTER TABLE `deliveries`
|
|||||||
ALTER TABLE `drops`
|
ALTER TABLE `drops`
|
||||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
|
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- AUTO_INCREMENT for table `pending_orders`
|
||||||
|
--
|
||||||
|
ALTER TABLE `pending_orders`
|
||||||
|
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- AUTO_INCREMENT for table `sales`
|
-- AUTO_INCREMENT for table `sales`
|
||||||
--
|
--
|
||||||
@@ -146,6 +184,13 @@ ALTER TABLE `sales`
|
|||||||
ALTER TABLE `deliveries`
|
ALTER TABLE `deliveries`
|
||||||
ADD CONSTRAINT `deliveries_ibfk_1` FOREIGN KEY (`sale_id`) REFERENCES `sales` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
ADD CONSTRAINT `deliveries_ibfk_1` FOREIGN KEY (`sale_id`) REFERENCES `sales` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Constraints for table `pending_orders`
|
||||||
|
--
|
||||||
|
ALTER TABLE `pending_orders`
|
||||||
|
ADD CONSTRAINT `pending_orders_ibfk_1` FOREIGN KEY (`drop_id`) REFERENCES `drops` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
|
ADD CONSTRAINT `pending_orders_ibfk_2` FOREIGN KEY (`buyer_id`) REFERENCES `buyers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Constraints for table `sales`
|
-- Constraints for table `sales`
|
||||||
--
|
--
|
||||||
|
|||||||
BIN
public/header.jpg
Normal file
BIN
public/header.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
Reference in New Issue
Block a user