added the shirts form. It mostly works except for deleting shirts
doesn't work as one would expect
This commit is contained in:
@@ -0,0 +1,63 @@
|
|||||||
|
export async function load({ }) {
|
||||||
|
console.log("shirt preorder page")
|
||||||
|
}
|
||||||
|
|
||||||
|
import { SMTP_USERNAME } from '$env/static/private'
|
||||||
|
import { transporter } from "$lib/email"
|
||||||
|
export const actions = {
|
||||||
|
default: async ({ request }) => {
|
||||||
|
let data = await request.formData();
|
||||||
|
// console.log("apply", data);
|
||||||
|
let order = {
|
||||||
|
name: data.get('name'),
|
||||||
|
email: data.get('email'),
|
||||||
|
amount: data.get('amount'),
|
||||||
|
estimated_price: data.get('estimated_price'),
|
||||||
|
}
|
||||||
|
console.log("appl", order, data)
|
||||||
|
|
||||||
|
const shirt_string = "test"
|
||||||
|
// const shirt_string = [
|
||||||
|
// shirt.name,
|
||||||
|
// shirt.city,
|
||||||
|
// shirt.contact?.name,
|
||||||
|
// ].map(v => {
|
||||||
|
// // Escape for CSV safety
|
||||||
|
// const s = String(v ?? '');
|
||||||
|
// return s.includes(',') || s.includes('"') ? `"${s.replace(/"/g, '""')}"` : s;
|
||||||
|
// }).join(', ');
|
||||||
|
|
||||||
|
console.log(shirt_string)
|
||||||
|
// transporter.sendMail({
|
||||||
|
// from: SMTP_USERNAME,
|
||||||
|
// to: "farm@sludge.link",
|
||||||
|
// subject: "Sludge Farm Shirt Preorder",
|
||||||
|
// attachments: [{
|
||||||
|
// filename: order.name + '-shirts.csv',
|
||||||
|
// content: shirt_string
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// filename: order.name + '-shirts.json',
|
||||||
|
// content: JSON.stringify(order)
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
// html: `
|
||||||
|
// <!doctype html>
|
||||||
|
// <html>
|
||||||
|
// <body>
|
||||||
|
// <h1>new order for ${order.name}!!</h1>
|
||||||
|
// <pre> ${JSON.stringify(order, null, 2).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')} </pre>
|
||||||
|
// </body>
|
||||||
|
// </html
|
||||||
|
// `
|
||||||
|
// }, (error, info) => {
|
||||||
|
// if (error) {
|
||||||
|
// console.error("Error sending email:", error);
|
||||||
|
// } else {
|
||||||
|
// console.log("Email sent successfully:", info.response);
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,212 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
const decoration = 3.5;
|
||||||
|
const USD = new Intl.NumberFormat("en-US", {
|
||||||
|
style: "currency",
|
||||||
|
currency: "USD",
|
||||||
|
minimumFractionDigits: 2,
|
||||||
|
});
|
||||||
|
const shirt_types = [
|
||||||
|
{ shirt_type: "6030", name: "Comfort Colors" },
|
||||||
|
{ shirt_type: "PC61PT", name: "Port & Co Pocket Talls" },
|
||||||
|
{ shirt_type: "PC61P", name: "Port & Co Pocket" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const shirt_sizes = ["S", "M", "L", "XL", "2XL", "3XL", "4XL"];
|
||||||
|
|
||||||
|
const shirt_styles = [
|
||||||
|
{
|
||||||
|
blurb:
|
||||||
|
"100% cotton with cool pastel colors with a washed fade; suspender sun fade not included",
|
||||||
|
href: "https://ssactivewear.com/p/comfort_colors/6030",
|
||||||
|
style_name: "Comfort Colors",
|
||||||
|
cost: 13.65,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
blurb:
|
||||||
|
"DoubleOG Will shirts for humans with plentiful rotundity, or tall torso's I suppose. I get them to go over ma belly.",
|
||||||
|
href: "https://www.sanmar.com/p/5771",
|
||||||
|
style_name: "Port & Co Essential Pocket Tee Tall",
|
||||||
|
cost: 14.3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
blurb:
|
||||||
|
"OG Will shirts in regular belly size, no belly button barbed wire holes however",
|
||||||
|
href: "https://www.sanmar.com/p/1300",
|
||||||
|
style_name: "Port & Co Essential Pocket Tee",
|
||||||
|
cost: 11.3,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const default_shirt = {
|
||||||
|
type: "",
|
||||||
|
color: "Type one from the website",
|
||||||
|
size: "",
|
||||||
|
};
|
||||||
|
function add_shirt() {
|
||||||
|
shirts = shirts.concat(default_shirt);
|
||||||
|
}
|
||||||
|
function remove_shirt(index: number) {
|
||||||
|
console.log(index, shirts);
|
||||||
|
shirts.splice(index, 1);
|
||||||
|
console.log(shirts);
|
||||||
|
}
|
||||||
|
|
||||||
|
let shirts = $state([default_shirt]);
|
||||||
|
let estimated_price = $derived(shirts.length * 17);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<form method="POST">
|
||||||
|
<fieldset>
|
||||||
|
<legend>Shirt Styles</legend>
|
||||||
|
<p>
|
||||||
|
All these shirts are 6.1 ounce, 100% cotton (unless you get the heather or
|
||||||
|
safety colors). It makes them a little heavier; but they actually survive
|
||||||
|
active wear as a work shirt. Of course with the resplendent pocket.
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
{#each shirt_styles as { style_name, cost, blurb, href }}
|
||||||
|
<li>
|
||||||
|
<a target="_blank" {href}>
|
||||||
|
{style_name}
|
||||||
|
</a>
|
||||||
|
<span>{USD.format(cost + decoration)}</span>
|
||||||
|
<p>{blurb}</p>
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset>
|
||||||
|
<legend> Request </legend>
|
||||||
|
<div>
|
||||||
|
<label for="name">Name:</label>
|
||||||
|
<input required name="name" type="text" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="email">Email:</label>
|
||||||
|
<input required name="email" type="email" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>
|
||||||
|
{shirts.length} shirt{shirts.length > 1 ? "s" : ""} for roughly ≈
|
||||||
|
{USD.format(estimated_price)}
|
||||||
|
</span>
|
||||||
|
<input
|
||||||
|
hidden
|
||||||
|
readonly
|
||||||
|
name="amount"
|
||||||
|
type="number"
|
||||||
|
bind:value={shirts.length}
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
hidden
|
||||||
|
readonly
|
||||||
|
name="estimated_price"
|
||||||
|
type="number"
|
||||||
|
bind:value={estimated_price}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<button type="button" onclick={add_shirt}>Add Shirt</button>
|
||||||
|
<div>
|
||||||
|
<ul>
|
||||||
|
{#each shirts as shirt, i}
|
||||||
|
<li>
|
||||||
|
<h4>Shirt #{i + 1}</h4>
|
||||||
|
<div>
|
||||||
|
<label for="type">Type:</label>
|
||||||
|
<select required name="type">
|
||||||
|
{#each shirt_types as { shirt_type, name }}
|
||||||
|
<option value={shirt_type}>{name}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="color">Color Name from Website:</label>
|
||||||
|
<input
|
||||||
|
required
|
||||||
|
type="text"
|
||||||
|
name="color"
|
||||||
|
placeholder={shirt.color}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="size">Size:</label>
|
||||||
|
<select required name="size">
|
||||||
|
{#each shirt_sizes as size}
|
||||||
|
<option>{size}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<button type="button" onclick={() => remove_shirt(i)}>
|
||||||
|
Remove
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<button>Submit</button>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
form {
|
||||||
|
max-width: 45rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
align-items: center;
|
||||||
|
fieldset {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
background: transparent(var(--secondary-5));
|
||||||
|
border-radius: var(--br);
|
||||||
|
padding: 0.25rem 1rem 1rem;
|
||||||
|
legend {
|
||||||
|
border-radius: var(--br);
|
||||||
|
background: var(--secondary-7);
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
li {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
ul {
|
||||||
|
li {
|
||||||
|
gap: 1rem;
|
||||||
|
align-items: center;
|
||||||
|
div {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
select,
|
||||||
|
button {
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: var(--primary-8);
|
||||||
|
border-radius: var(--br);
|
||||||
|
border: none;
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
width: 25rem;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
font-weight: 700;
|
||||||
|
width: fit-content;
|
||||||
|
background: transparent(var(--secondary-5));
|
||||||
|
align-self: center;
|
||||||
|
color: var(--primary-1);
|
||||||
|
&:hover {
|
||||||
|
background: var(--secondary-6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user