first
This commit is contained in:
1567
package-lock.json
generated
Normal file → Executable file
1567
package-lock.json
generated
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "auburnoil",
|
||||
"name": "newenglandbio",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
0
public/favicon.ico
Normal file → Executable file
0
public/favicon.ico
Normal file → Executable file
|
Before Width: | Height: | Size: 318 B After Width: | Height: | Size: 318 B |
0
public/robots.txt
Normal file → Executable file
0
public/robots.txt
Normal file → Executable file
0
src/favicon.png
Normal file → Executable file
0
src/favicon.png
Normal file → Executable file
|
Before Width: | Height: | Size: 318 B After Width: | Height: | Size: 318 B |
113
src/lib/types/types.ts
Normal file → Executable file
113
src/lib/types/types.ts
Normal file → Executable file
@@ -1,103 +1,20 @@
|
||||
|
||||
|
||||
export type oilprice = {
|
||||
ok: boolean
|
||||
todays_price: string;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export type RegisterRequest = {
|
||||
email: string;
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export type priceitems = {
|
||||
ok: boolean
|
||||
price_emergency: string;
|
||||
price_prime: string;
|
||||
price_same_day: string;
|
||||
export type LoginRequest = {
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
export type company = {
|
||||
ok: boolean
|
||||
company_name: string;
|
||||
company_phone_number: string;
|
||||
|
||||
}
|
||||
|
||||
|
||||
export type deliverytype = {
|
||||
ok: boolean
|
||||
id: number;
|
||||
customer_id: string;
|
||||
customer_name: string;
|
||||
customer_address: string;
|
||||
customer_town: string;
|
||||
customer_state: number;
|
||||
customer_zip: string;
|
||||
gallons_ordered: number;
|
||||
customer_asked_for_fill: number;
|
||||
gallons_delivered: string;
|
||||
customer_filled: number;
|
||||
delivery_status: number;
|
||||
when_ordered: string;
|
||||
when_delivered: string;
|
||||
expected_delivery_date: string;
|
||||
automatic: number;
|
||||
oil_id: number;
|
||||
supplier_price: string;
|
||||
customer_price: string;
|
||||
customer_temperature: string;
|
||||
dispatcher_notes: string;
|
||||
prime: number;
|
||||
same_day: number;
|
||||
payment_type: number;
|
||||
payment_card_id: number;
|
||||
driver_employee_id: number;
|
||||
driver_first_name: string;
|
||||
driver_last_name: string;
|
||||
|
||||
}
|
||||
|
||||
export type customertype = {
|
||||
ok: boolean
|
||||
id: number;
|
||||
user_id: number;
|
||||
customer_first_name: string;
|
||||
customer_last_name: string;
|
||||
customer_town: string;
|
||||
customer_address: string;
|
||||
customer_state: number;
|
||||
customer_zip: string;
|
||||
customer_apt: string;
|
||||
customer_home_type: number;
|
||||
customer_phone_number: string;
|
||||
account_number: string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
export type pastdeliverytype = {
|
||||
ok: boolean
|
||||
id: number;
|
||||
customer_id: string;
|
||||
customer_name: string;
|
||||
customer_address: string;
|
||||
customer_town: string;
|
||||
customer_state: number;
|
||||
customer_zip: string;
|
||||
gallons_ordered: number;
|
||||
customer_asked_for_fill: number;
|
||||
gallons_delivered: string;
|
||||
customer_filled: number;
|
||||
delivery_status: number;
|
||||
when_ordered: string;
|
||||
when_delivered: string;
|
||||
expected_delivery_date: string;
|
||||
automatic: number;
|
||||
oil_id: number;
|
||||
supplier_price: string;
|
||||
customer_price: string;
|
||||
customer_temperature: string;
|
||||
dispatcher_notes: string;
|
||||
prime: number;
|
||||
same_day: number;
|
||||
payment_type: number;
|
||||
payment_card_id: number;
|
||||
driver_employee_id: number;
|
||||
driver_first_name: string;
|
||||
driver_last_name: string;
|
||||
}
|
||||
@@ -1,192 +1,22 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import { PUBLIC_BASE_URL } from "$env/static/public";
|
||||
import type { company, oilprice } from '$lib/types/types'
|
||||
export let company_data: company;
|
||||
export let oil_price_data: oilprice;
|
||||
|
||||
let price_of_oil: string = '';
|
||||
let company_name: string = '';
|
||||
let company_phone_number: string = '';
|
||||
|
||||
onMount(async () => {
|
||||
await fetch(PUBLIC_BASE_URL + "/info/price/today", {
|
||||
method: "get",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((result) => (oil_price_data = result));
|
||||
|
||||
if (oil_price_data["ok"] == true) {
|
||||
price_of_oil = oil_price_data["todays_price"];
|
||||
|
||||
}
|
||||
});
|
||||
onMount(async () => {
|
||||
await fetch(PUBLIC_BASE_URL + "/info/company", {
|
||||
method: "get",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((result) => (company_data = result));
|
||||
|
||||
if (company_data["ok"] == true) {
|
||||
company_name = company_data["company_name"];
|
||||
company_phone_number = company_data["company_phone_number"];
|
||||
}
|
||||
});
|
||||
import '../../app.postcss'; // Import Tailwind CSS
|
||||
</script>
|
||||
|
||||
<html lang="en">
|
||||
<div class="min-h-screen bg-white flex flex-col">
|
||||
<header class="navbar bg-primary text-primary-content shadow-lg">
|
||||
<div class="flex-1">
|
||||
<a href="/" class="btn btn-ghost normal-case text-xl">Heating Price Hero</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<head>
|
||||
<main class="flex-grow container mx-auto p-4">
|
||||
<slot />
|
||||
</main>
|
||||
|
||||
<!-- Google tag (gtag.js) -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-7R7B94HG9M"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', 'G-7R7B94HG9M');
|
||||
</script>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<meta name="description" content="Auburn Oil provides reliable heating oil delivery and top quality oil.
|
||||
Serving homes in Auburn, Worcester, Oxford, Sutton, and Webster. ">
|
||||
</head>
|
||||
|
||||
|
||||
<div class="grid grid-cols-12 bg-blue-oil overflow-hidden">
|
||||
<div class="col-span-12 md:col-span-3 text-3xl p-10 text-orange-oil font-bold invisible md:visible h-0 md:h-auto">
|
||||
<div class="text-center pt-5 text-white">Call Today</div>
|
||||
<div class="text-center ">{company_phone_number}</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 md:col-span-6 md:p-10 text-center font-bold ">
|
||||
<div class="md:flex md:justify-center pb-5 md:pb-0 gap-5">
|
||||
<a href="/">
|
||||
<img class="" src="/images/logo/1.png" alt="Auburn Oil Near Me" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div
|
||||
class=" col-span-12 md:col-span-3 md:p-10 text-3xl text-orange-oil font-bold"
|
||||
>
|
||||
<div class="text-center pt-5 text-white">Todays Price</div>
|
||||
<div class="text-center ">${price_of_oil}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="navbar bg-orange-oil text-white">
|
||||
<div class="navbar-start">
|
||||
<div class="dropdown">
|
||||
<div tabindex="0" role="button" class="btn btn-ghost hover:bg-blue-oil lg:hidden">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-5 w-5"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
><path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M4 6h16M4 12h8m-8 6h16"
|
||||
/></svg
|
||||
>
|
||||
</div>
|
||||
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
||||
<ul
|
||||
tabindex="0"
|
||||
class="menu menu-sm bg-orange-oil w-64 dropdown-content mt-3 z-[1] p-2 shadow rounded-box font-bold text-white"
|
||||
>
|
||||
<li><a class="text-2xl py-2 hover:bg-blue-900" href="/">Home</a></li>
|
||||
<li><a class="text-2xl py-2 hover:bg-blue-900" href="/oil">Our Oil</a></li>
|
||||
<li><a class="text-2xl py-2 hover:bg-blue-900" href="/delivery">Delivery</a></li>
|
||||
<li><a class="text-2xl py-2 hover:bg-blue-900" href="/servicearea">Delivery Area</a></li>
|
||||
<li><a class="text-2xl py-2 hover:bg-blue-900" href="/about">About Us</a></li>
|
||||
<li><a class="text-2xl py-2 hover:bg-blue-900" href="/contact">Contact</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="navbar-center hidden lg:flex ">
|
||||
<ul class="menu menu-horizontal px-1 text-xl">
|
||||
<li class="hover:bg-blue-900 hover:rounded hover:text-white text-white"><a href="/">Home</a></li>
|
||||
<li class="hover:bg-blue-900 hover:rounded hover:text-white text-white"><a href="/oil">Our Oil</a></li>
|
||||
<li class="hover:bg-blue-900 hover:rounded hover:text-white text-white"><a href="/delivery">Delivery</a></li>
|
||||
<li class="hover:bg-blue-900 hover:rounded hover:text-white text-white"><a href="/servicearea">Delivery Area</a></li>
|
||||
<li class="hover:bg-blue-900 hover:rounded hover:text-white text-white"><a href="/about">About Us</a></li>
|
||||
<li class="hover:bg-blue-900 hover:rounded hover:text-white text-white"><a href="/contact">Contact</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="navbar-end ">
|
||||
|
||||
</div>
|
||||
<footer class="footer footer-center p-4 bg-base-300 text-base-content">
|
||||
<div>
|
||||
<p>Copyright © {new Date().getFullYear()} - All right reserved</p>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
<body>
|
||||
<div class="body bg-white text-black">
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
</body>
|
||||
<footer>
|
||||
<div class="grid grid-cols-12 bg-blue-oil py-10 w-full">
|
||||
<div
|
||||
class="col-span-12 md:col-span-4 text-center text-white text-bold text-6xl "
|
||||
>
|
||||
<div class="flex justify-center pt-5">
|
||||
<img class="" src="/images/logo/2.png" alt="Heating Oil lowest price near me" />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="col-span-12 md:col-span-4 text-center text-bold text-xl text-white pb-10"
|
||||
>
|
||||
<div class="">{company_phone_number}</div>
|
||||
<div class="">P.O. Box 174</div>
|
||||
<div class="">Auburn Ma 01501</div>
|
||||
<div class="">Mon - Fri 8:00 am - 5:00 pm</div>
|
||||
<div class="">Sat Closed | Sun Closed</div>
|
||||
<div class="px-5 py-5 flex justify-center">
|
||||
<a href="https://www.facebook.com/auburnoil">
|
||||
<img class="px-5" src="/images/social/facebook.png" alt="Heating Oil lowest price near me" />
|
||||
</a>
|
||||
<a href="https://g.co/kgs/srVz9CQ">
|
||||
|
||||
<img class="" src="/images/social/google.png" alt="Heating Oil lowest price near me" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="col-span-12 md:col-span-4 pb-10 text-center">
|
||||
<div class="flex-1"><a href="/">Home</a></div>
|
||||
<div class="flex-1"><a href="/delivery">Oil Delivery</a></div>
|
||||
<div class="flex-1"><a href="/servicearea">Delivery Area</a></div>
|
||||
<div class="flex-1"><a href="/about">About Us</a></div>
|
||||
<div class="flex-1"><a href="/contact">Contact</a></div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 h-auto bg-secondary text-white w-full ">
|
||||
<div class=" mx-auto max-w-7xl p-5">
|
||||
<div class="text-xl font-bold text-center">
|
||||
© 2023 by Rocket Services LLC - Auburn, MA | All Rights Reserved
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</html>
|
||||
@@ -1,183 +1,74 @@
|
||||
<!-- src/routes/+page.svelte -->
|
||||
<script lang="ts">
|
||||
import "../../app.postcss";
|
||||
import { onMount } from "svelte";
|
||||
import { PUBLIC_BASE_URL } from "$env/static/public";
|
||||
import type { company, oilprice } from '$lib/types/types'
|
||||
import { newEnglandStates, mapViewBox } from '$lib/states';
|
||||
import { goto } from '$app/navigation';
|
||||
import { browser } from '$app/environment'; // To ensure SVG interactions only run client-side
|
||||
|
||||
export let company_data: company;
|
||||
export let oil_price_data: oilprice;
|
||||
|
||||
let hoveredState: string | null = null;
|
||||
|
||||
let price_of_oil: string = '';
|
||||
let company_name: string = '';
|
||||
let company_phone_number: string = '';
|
||||
|
||||
|
||||
onMount(async () => {
|
||||
await fetch(PUBLIC_BASE_URL + "/info/price/today", {
|
||||
method: "get",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((result) => (oil_price_data = result));
|
||||
|
||||
if (oil_price_data["ok"] == true) {
|
||||
price_of_oil = oil_price_data["todays_price"];
|
||||
function handleStateClick(id: string) {
|
||||
goto(`/${id}`);
|
||||
}
|
||||
});
|
||||
onMount(async () => {
|
||||
await fetch(PUBLIC_BASE_URL + "/info/company", {
|
||||
method: "get",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((result) => (company_data = result));
|
||||
|
||||
if (company_data["ok"] == true) {
|
||||
company_name = company_data["company_name"];
|
||||
company_phone_number = company_data["company_phone_number"];
|
||||
function handleMouseEnter(stateId: string) {
|
||||
if (browser) {
|
||||
hoveredState = stateId;
|
||||
}
|
||||
}
|
||||
|
||||
function handleMouseLeave() {
|
||||
if (browser) {
|
||||
hoveredState = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<title>Auburn Oil: Quality Heating Oil Delivery in Southern Worcester County</title>
|
||||
|
||||
<div class="bg-blue-oil text-white">
|
||||
<div class="bg-secondary px-10">
|
||||
<div class="max-w-7xl justify-center py-5 mx-auto font-bold text-white">
|
||||
<h1 class="text-center text-xl">Delivering Oil to Worcester County</h1>
|
||||
</div>
|
||||
<div class="text-center mb-8">
|
||||
|
||||
<p class="text-lg">Click your state to find prices.</p>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="mx-auto p-0 ">
|
||||
<a href="/delivery">
|
||||
<img class="mx-auto p-0 m-0 overflow-hidden" src="/images/truck.png" alt="Auburn Massachusetts" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="mx-auto p-10">
|
||||
<div class="mx-auto pb-5 text-5xl text-center">Order Now</div>
|
||||
<div class="mx-auto text-5xl text-center">
|
||||
{company_phone_number}
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-12 gap-5 px-5 text-center mt-10">
|
||||
<div class="col-span-12 font-bold text-4xl text-blue-400 mx-auto ">
|
||||
Why call Auburn Oil?
|
||||
</div>
|
||||
<!-- <div class="col-span-12 lg:col-span-1"></div> -->
|
||||
<div class="col-span-12 lg:col-span-4 bg-base-100 p-10 ">
|
||||
<div class="text-4xl mb-3">Cheaper Prices</div>
|
||||
<div class="text-lg">
|
||||
No Middleman. No expensive bulk plants. Direct port to door for
|
||||
cheapest prices.
|
||||
<div class="flex justify-center items-center">
|
||||
{#if browser}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox={mapViewBox}
|
||||
class="w-full max-w-md h-auto border border-gray-300 rounded-lg shadow-md"
|
||||
aria-labelledby="mapTitle"
|
||||
role="img"
|
||||
>
|
||||
<title id="mapTitle">Interactive Map of New England States</title>
|
||||
{#each newEnglandStates as state}
|
||||
<path
|
||||
d={state.pathD}
|
||||
class={`stroke-black stroke-1 cursor-pointer transition-all duration-150 ease-in-out
|
||||
${hoveredState === state.id ? state.hoverFill : state.fill}`}
|
||||
on:click={() => handleStateClick(state.id)}
|
||||
on:mouseenter={() => handleMouseEnter(state.id)}
|
||||
on:mouseleave={handleMouseLeave}
|
||||
aria-label={state.id}
|
||||
tabindex="0"
|
||||
role="link"
|
||||
on:keydown={(e) => { if (e.key === 'Enter' || e.key === ' ') handleStateClick(state.id)}}
|
||||
>
|
||||
<title>{state.name}</title> <!-- Tooltip on hover -->
|
||||
</path>
|
||||
{/each}
|
||||
</svg>
|
||||
{:else}
|
||||
<div class="w-full max-w-2xl h-[500px] bg-gray-200 animate-pulse rounded-lg flex justify-center items-center">
|
||||
<p>Loading map...</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-12 lg:col-span-4 bg-base-100 p-10">
|
||||
<div class="text-4xl mb-3">Phone Support</div>
|
||||
<div class="text-lg">
|
||||
Real live person on the phone when you call.
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-12 lg:col-span-4 bg-base-100 p-10">
|
||||
<div class="text-4xl mb-3">Top Quality Oil</div>
|
||||
<div class="text-lg">
|
||||
We dont cut our oil with biodiesel. We use the best available
|
||||
fuel for your heating system
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="col-span-12 lg:col-span-1"></div> -->
|
||||
<div class="col-span-12 lg:text-center text-center bg-orange-oil">
|
||||
<div class="text-3xl ">
|
||||
We Offer Automatic Delivery
|
||||
</div>
|
||||
<div class="text-xl p-5">We will automatically fill your home and keep your family comfortable without worries
|
||||
about oil levels.
|
||||
</div>
|
||||
<div class="text-xl">Always get priority delivery status.</div>
|
||||
</div>
|
||||
<div class="col-span-6 text-lg text-center">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="h-auto">
|
||||
<div class="mx-auto p-5">
|
||||
<div class="grid grid-cols-12">
|
||||
<div class="col-span-12 py-5">
|
||||
<div
|
||||
class="font-bold text-5xl text-blue-400 max-w-7xl mx-auto text-center md:text-left"
|
||||
>
|
||||
Serving these communites
|
||||
</div>
|
||||
<div
|
||||
class="font-bold text-xl bg-blue-400 text-blue-800 h-10 mb-10"
|
||||
></div>
|
||||
</div>
|
||||
<div class="col-span-12 py-5">
|
||||
<div
|
||||
class="invisible md:visible h-0 md:h-auto flex gap-20 justify-center text-2xl"
|
||||
>
|
||||
<div >
|
||||
<div class="text-2xl">Auburn</div>
|
||||
<div class="text-2xl">Millbury</div>
|
||||
<div class="text-2xl">Sutton</div>
|
||||
<div class="text-2xl">Oxford</div>
|
||||
<div class="text-2xl">North Oxford</div>
|
||||
<div class="text-2xl">Webster</div>
|
||||
<div class="text-2xl">SouthBridge</div>
|
||||
<div class="text-2xl">Shrewsbury</div>
|
||||
<div class="text-2xl">Grafton</div>
|
||||
</div>
|
||||
<div >
|
||||
<div class="text-2xl">Dudley</div>
|
||||
<div class="text-2xl">Sutton</div>
|
||||
<div class="text-2xl">Charlton</div>
|
||||
<div class="text-2xl">Leicester</div>
|
||||
<div class="text-2xl">Cherry Valley</div>
|
||||
<div class="text-2xl">Rochdale</div>
|
||||
<div class="text-2xl">Spencer</div>
|
||||
<div class="text-2xl">Southbridge</div>
|
||||
<div class="text-2xl">Worcester</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="visible sm:visible md:invisible h-auto sm:h-auto md:h-0">
|
||||
<div class="text-center">
|
||||
<div class="text-2xl">Auburn</div>
|
||||
<div class="text-2xl">Millbury</div>
|
||||
<div class="text-2xl">Sutton</div>
|
||||
<div class="text-2xl">Oxford</div>
|
||||
<div class="text-2xl">North Oxford</div>
|
||||
<div class="text-2xl">Webster</div>
|
||||
<div class="text-2xl">Southbridge</div>
|
||||
<div class="text-2xl">Shrewsbury</div>
|
||||
<div class="text-2xl">Grafton</div>
|
||||
<div class="text-2xl">Dudley</div>
|
||||
<div class="text-2xl">Charlton</div>
|
||||
<div class="text-2xl">Leicester</div>
|
||||
<div class="text-2xl">Cherry Valley</div>
|
||||
<div class="text-2xl">Rochdale</div>
|
||||
<div class="text-2xl">Spencer</div>
|
||||
<div class="text-2xl">Sutton</div>
|
||||
<div class="text-2xl">Southbridge</div>
|
||||
<div class="text-2xl">Worcester</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-12 py-5">
|
||||
<div class="flex justify-center items-center ">
|
||||
<img class="" src="/images/area.png" alt="Worcester County oil delivery" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="mt-8 text-center">
|
||||
<h2 class="text-2xl font-semibold mb-4">States:</h2>
|
||||
<ul class="flex flex-wrap justify-center gap-4">
|
||||
{#each newEnglandStates as state}
|
||||
<li>
|
||||
<a href="/{state.id}" class="btn btn-outline btn-secondary">{state.name}</a>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
85
src/routes/(app)/[stateSlug]/+page.svelte
Executable file
85
src/routes/(app)/[stateSlug]/+page.svelte
Executable file
@@ -0,0 +1,85 @@
|
||||
<!-- src/routes/[stateSlug]/+page.svelte -->
|
||||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
import { newEnglandStates, allCounties, type NewEnglandState } from '$lib/states'; // <--- Import type and counties
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
// The stateSlug from $page.params is guaranteed to be a string if this route matches
|
||||
// because [stateSlug] is a required parameter.
|
||||
const { stateSlug } = $page.params as { stateSlug: string }; // Type assertion for clarity
|
||||
|
||||
let stateData: NewEnglandState | undefined;
|
||||
let filteredCounties: any[] = [];
|
||||
let loading = false;
|
||||
let error: string | null = null;
|
||||
|
||||
onMount(async () => {
|
||||
stateData = newEnglandStates.find(s => s.id === stateSlug);
|
||||
if (stateData) {
|
||||
loading = true;
|
||||
try {
|
||||
const response = await fetch(`http://localhost:9552/state/${stateSlug.toUpperCase()}`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`API call failed with status ${response.status}`);
|
||||
}
|
||||
filteredCounties = await response.json();
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to fetch counties';
|
||||
filteredCounties = [];
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
{#if stateData}
|
||||
<div class="card lg:card-side bg-base-100 shadow-xl">
|
||||
<figure class=" ">
|
||||
<img
|
||||
src={stateData.image}
|
||||
alt="Map or notable feature of {stateData.id}"
|
||||
class="object-cover"
|
||||
/>
|
||||
</figure>
|
||||
<div class="card-body lg:w-1/2">
|
||||
<h1 class="card-title text-4xl">{stateData.name}</h1>
|
||||
<p>This is the page for {stateData.name}. Here you can add more specific information about this wonderful state!</p>
|
||||
<p>The URL for this page is <code class="bg-base-300 p-1 rounded">/{stateData.id}</code> which is {stateData.id.length} characters long.</p>
|
||||
<div class="mt-4">
|
||||
<h2 class="text-xl font-semibold mb-2">Counties:</h2>
|
||||
{#if loading}
|
||||
<p>Loading counties...</p>
|
||||
{:else if error}
|
||||
<p class="text-error">Error: {error}</p>
|
||||
{:else}
|
||||
<ul class="list-disc pl-5">
|
||||
{#each filteredCounties as county}
|
||||
<li>
|
||||
<a href="http://localhost:9551/{stateSlug.toUpperCase()}/{county.id}" class="text-blue-600 hover:underline">{county.name}</a>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="card-actions justify-end mt-4">
|
||||
<a href="/" class="btn btn-primary">Back to Map</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{:else if !stateData && stateSlug} <!-- Check if stateData is still undefined after onMount attempted to find it -->
|
||||
<div class="text-center py-10">
|
||||
<h1 class="text-3xl font-bold text-error">State Not Found</h1>
|
||||
<p class="mt-4">Could not find information for a state with ID: "{stateSlug}".</p>
|
||||
<a href="/" class="btn btn-primary mt-6">Go Back to Map</a>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
figure img {
|
||||
object-fit: cover;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
44
src/routes/(app)/[stateSlug]/[countySlug]/+page.svelte
Normal file
44
src/routes/(app)/[stateSlug]/[countySlug]/+page.svelte
Normal file
@@ -0,0 +1,44 @@
|
||||
<!-- src/routes/(app)/[stateSlug]/[countySlug]/+page.svelte -->
|
||||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
const { stateSlug, countySlug } = $page.params as { stateSlug: string; countySlug: string };
|
||||
let countyData: { id: number; name: string; state: string } | null = null;
|
||||
let loading = true;
|
||||
let error: string | null = null;
|
||||
|
||||
onMount(async () => {
|
||||
try {
|
||||
// Ensure API URL matches the Docker port forwarding for API (9552)
|
||||
const response = await fetch(`http://localhost:9552/state/${stateSlug.toUpperCase()}/${countySlug}`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch county data: ${response.statusText}`);
|
||||
}
|
||||
countyData = await response.json();
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'An error occurred while fetching county data.';
|
||||
countyData = null;
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
});
|
||||
</script>3
|
||||
|
||||
{#if loading}
|
||||
<div class="text-center py-10">
|
||||
<p>Loading county data...</p>
|
||||
</div>
|
||||
{:else if countyData}
|
||||
<div class="text-center py-10">
|
||||
<h1 class="text-3xl font-bold">{countyData.name}</h1>
|
||||
<p class="text-xl mt-4">County ID: {countyData.id}</p>
|
||||
<a href="/{stateSlug}" class="btn btn-primary mt-6">Back to State</a>
|
||||
</div>
|
||||
{:else if error}
|
||||
<div class="text-center py-10">
|
||||
<h1 class="text-3xl font-bold text-error">County Not Found</h1>
|
||||
<p class="mt-4">{error}</p>
|
||||
<a href="/" class="btn btn-primary mt-6">Go Back to Map</a>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -1,67 +0,0 @@
|
||||
<script lang='ts'>
|
||||
import "../../../app.postcss";
|
||||
import { onMount } from "svelte";
|
||||
import { PUBLIC_BASE_URL } from "$env/static/public";
|
||||
import type { company } from '$lib/types/types'
|
||||
|
||||
export let company_data: company;
|
||||
|
||||
|
||||
let company_name: string = '';
|
||||
let tel_number: string = '';
|
||||
|
||||
onMount(async () => {
|
||||
await fetch(PUBLIC_BASE_URL + "/info/company", {
|
||||
method: "get",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((result) => (company_data = result));
|
||||
|
||||
if (company_data["ok"] == true) {
|
||||
company_name = company_data["company_name"];
|
||||
tel_number = company_data["company_phone_number"];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<title>About Auburn Oil </title>
|
||||
<div class="bg-secondary px-10">
|
||||
<div
|
||||
class="max-w-7xl justify-center py-5 mx-auto font-bold text-white"
|
||||
>
|
||||
<h1>About Us</h1>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="max-w-7xl mx-auto px-10">
|
||||
<div class="grid grid-cols-12 max-w-7xl gap-5">
|
||||
<div class="col-span-12 text-2xl text-bold"></div>
|
||||
<div class="col-span-12 md:col-span-6 mb-20">
|
||||
<div class="col-span-12 mb-5 font-bold text-xl text-primary">
|
||||
Mission Statement
|
||||
</div>
|
||||
<div class="col-span-12 text-lg pb-20">
|
||||
After watching the oil community add more bio every year to there deliveries, we decided it was time to bring back some integrity to the oil industry.
|
||||
Auburn oil was born with the idea of selling the purest heating oil we can deliver to our customers. Our slogan is "oil you can trust" and we stand behind it.
|
||||
We are not adding more bio to your oil
|
||||
every year to increase profits at the expense of the customer. You call, we deliver top quality oil.
|
||||
</div>
|
||||
<div class="col-span-12 mb-5 font-bold text-xl text-primary">
|
||||
Our history of delivering oil
|
||||
</div>
|
||||
<div class="col-span-12 text-lg pb-20">
|
||||
After 20 years delivering for other companies in Worcester. Our family
|
||||
decided it was time to start a small business to serve customers. We have the
|
||||
experience to ensure your family stays warm! Everyone in our family is a certified boiler technician.
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-span-12 md:col-span-6">
|
||||
<img class="w-full p-0 m-0" src="/images/truckdog.png" alt="Delivering Oil" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,96 +0,0 @@
|
||||
<script lang="ts">
|
||||
import "../../../app.postcss";
|
||||
import { onMount } from "svelte";
|
||||
import { PUBLIC_BASE_URL } from "$env/static/public";
|
||||
import type { company, oilprice } from "$lib/types/types";
|
||||
|
||||
export let company_data: company;
|
||||
export let oil_price_data: oilprice;
|
||||
|
||||
let price_of_oil: string = "";
|
||||
let company_name: string = "";
|
||||
let company_phone_number: string = "";
|
||||
|
||||
onMount(async () => {
|
||||
await fetch(PUBLIC_BASE_URL + "/info/price/today", {
|
||||
method: "get",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((result) => (oil_price_data = result));
|
||||
|
||||
if (oil_price_data["ok"] == true) {
|
||||
price_of_oil = oil_price_data["todays_price"];
|
||||
}
|
||||
});
|
||||
onMount(async () => {
|
||||
await fetch(PUBLIC_BASE_URL + "/info/company", {
|
||||
method: "get",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((result) => (company_data = result));
|
||||
|
||||
if (company_data["ok"] == true) {
|
||||
company_name = company_data["company_name"];
|
||||
company_phone_number = company_data["company_phone_number"];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<title>Contact Auburn Oil </title>
|
||||
<div class="bg-secondary px-10">
|
||||
<div
|
||||
class="max-w-7xl justify-center py-5 mx-auto font-bold text-white"
|
||||
>
|
||||
<h1>Contact</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="max-w-7xl mx-auto px-10">
|
||||
<div class="grid grid-cols-2 gap-5">
|
||||
<div class="col-span-2 md:col-span-1">
|
||||
<div class="text-2xl font-bold text-primary">Contact Us</div>
|
||||
<div class=" text-xl">Phone: {company_phone_number}</div>
|
||||
<div class=" text-xl">Email: auburnoilservices@gmail.com</div>
|
||||
<div class="mb-10 "></div>
|
||||
<div class=" text-xl">Auburn Oil</div>
|
||||
<div class=" text-xl">P.O. Box 174</div>
|
||||
<div class=" text-xl">Auburn Ma 01501</div>
|
||||
<div class="mb-10 "></div>
|
||||
<div class="mb-10">
|
||||
<div class="font-bold text-2xl text-primary max-w-7xl mx-auto">
|
||||
Business Hours Summer
|
||||
</div>
|
||||
<div class="font-bold text-xl bg-primary text-white h-2 mb-2"></div>
|
||||
<div class="text-xl">Monday: 8:00 a.m. – 5:00 p.m.</div>
|
||||
<div class="text-xl">Tuesday: 8:00 a.m. – 5:00 p.m.</div>
|
||||
<div class="text-xl">Wednesday: 8:00 a.m. – 5:00 p.m.</div>
|
||||
<div class="text-xl">Thursday: 8:00 a.m. – 5:00 p.m.</div>
|
||||
<div class="text-xl">Friday: 8:00 a.m. – 3:00 p.m.</div>
|
||||
<div class="text-xl">Saturday: Closed</div>
|
||||
<div class="text-xl">Sunday: Closed</div>
|
||||
</div>
|
||||
<div class="pb-10">
|
||||
<div class="font-bold text-2xl text-primary max-w-7xl mx-auto">
|
||||
Business Hours Winter
|
||||
</div>
|
||||
<div class="font-bold text-xl bg-primary text-white h-2 mb-2"></div>
|
||||
<div class="text-xl">Monday: 8:00 a.m. – 5:00 p.m.</div>
|
||||
<div class="text-xl">Tuesday: 8:00 a.m. – 5:00 p.m.</div>
|
||||
<div class="text-xl">Wednesday: 8:00 a.m. – 5:00 p.m.</div>
|
||||
<div class="text-xl">Thursday: 8:00 a.m. – 5:00 p.m.</div>
|
||||
<div class="text-xl">Friday: 8:00 a.m. – 5:00 p.m.</div>
|
||||
<div class="text-xl">Saturday: 8:00 a.m. – 1:00 p.m.</div>
|
||||
<div class="text-xl">Sunday: Closed</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-2 md:col-span-1 ">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,146 +0,0 @@
|
||||
<script lang='ts'>
|
||||
import "../../../app.postcss";
|
||||
import { onMount } from "svelte";
|
||||
import { PUBLIC_BASE_URL } from "$env/static/public";
|
||||
import type { company, priceitems } from '$lib/types/types'
|
||||
|
||||
export let company_data: company;
|
||||
export let oil_data: priceitems;
|
||||
|
||||
let company_name: string = '';
|
||||
let tel_number: string = '';
|
||||
|
||||
let price_emergency: string = '';
|
||||
let price_prime: string = '';
|
||||
let price_same_day: string = '';
|
||||
|
||||
onMount(async () => {
|
||||
await fetch(PUBLIC_BASE_URL + "/info/company", {
|
||||
method: "get",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((result) => (company_data = result));
|
||||
|
||||
if (company_data["ok"] == true) {
|
||||
company_name = company_data["company_name"];
|
||||
tel_number = company_data["company_phone_number"];
|
||||
}
|
||||
});
|
||||
onMount(async () => {
|
||||
await fetch(PUBLIC_BASE_URL + "/info/price/oil/items", {
|
||||
method: "get",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((result) => (oil_data = result));
|
||||
|
||||
if (oil_data["ok"] == true) {
|
||||
price_emergency = oil_data["price_emergency"];
|
||||
price_prime = oil_data["price_prime"];
|
||||
price_same_day = oil_data["price_same_day"];
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
<title>Home Heating Oil Delivery</title>
|
||||
<div class="bg-secondary px-10">
|
||||
<div
|
||||
class="max-w-7xl justify-center py-5 mx-auto font-bold text-white"
|
||||
>
|
||||
<h1>Heating Oil Delivery</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="max-w-7xl mx-auto px-10">
|
||||
<div class="grid grid-cols-12 max-w-7xl">
|
||||
<div class="col-span-12 lg:col-span-6">
|
||||
<div class="grid grid-cols-12">
|
||||
|
||||
<div class="col-span-12 font-bold text-2xl my-10">
|
||||
We know it can be tough to order oil. We make it simple!
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-span-12 font-bold text-xl text-primary">
|
||||
Worcester County
|
||||
</div>
|
||||
<div class="col-span-12 text-lg">
|
||||
<ul>100 Gallon Minimum to Worcester County</ul>
|
||||
<ul>Prime - ${price_prime}</ul>
|
||||
<ul>Same Day - ${price_same_day} + price oil</ul>
|
||||
<ul>After Hours Emergency - ${price_emergency} + price oil (prime included)</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-span-12 font-bold mt-10 text-xl text-primary">
|
||||
Payments Methods
|
||||
</div>
|
||||
<div class="col-span-12 text-lg">
|
||||
<ul>Cash on Delivery (C.O.D)</ul>
|
||||
<ul>Credit Card</ul>
|
||||
<ul>Money Order</ul>
|
||||
<ul>Check (with credit card hold till it clears)</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-span-12 mb-10">
|
||||
<ul>
|
||||
<div class="col-span-12 font-bold mt-10 text-xl text-primary">
|
||||
How to Order Oil
|
||||
</div>
|
||||
<div class="flex gap-5">
|
||||
|
||||
<li class=" font-bold">
|
||||
1.) Call {tel_number} to place an order.
|
||||
</li>
|
||||
</div>
|
||||
<div class="flex gap-5">
|
||||
|
||||
<li class=" font-bold">
|
||||
2.) Give your name, address, fill location, and phone number.
|
||||
</li>
|
||||
</div>
|
||||
<div class="flex gap-5">
|
||||
<li class=" font-bold">
|
||||
3.) Decide if you want a fill or specific gallons
|
||||
</li>
|
||||
</div>
|
||||
<div class="flex gap-5">
|
||||
<li class=" font-bold">
|
||||
4.) Pay with above payments mentioned.
|
||||
|
||||
</li>
|
||||
</div>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 mx-auto py-10">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 md:col-span-6">
|
||||
<div class="col-span-12">
|
||||
<img alt="" class="w-full p-0 m-0" src="/images/truckauburn.png" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 mb-10
|
||||
text-bold bg-blue-oil text-white mt-10 text-5xl text-bold
|
||||
p-5 text-center">
|
||||
Call Today {tel_number}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
111
src/routes/(app)/login/+page.svelte
Executable file
111
src/routes/(app)/login/+page.svelte
Executable file
@@ -0,0 +1,111 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import type { LoginRequest } from '$lib/types/types';
|
||||
|
||||
let username = '';
|
||||
let password = '';
|
||||
let errorMessage = '';
|
||||
let isLoading = false;
|
||||
|
||||
async function handleSubmit() {
|
||||
const loginData: LoginRequest = {
|
||||
username,
|
||||
password
|
||||
};
|
||||
|
||||
isLoading = true;
|
||||
errorMessage = '';
|
||||
|
||||
try {
|
||||
const response = await fetch('/login', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(loginData)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json();
|
||||
errorMessage = errorData.error || 'Login failed';
|
||||
} else {
|
||||
const data = await response.json();
|
||||
// Assuming the backend returns a token or some success indicator
|
||||
// Redirect to home page or dashboard after successful login
|
||||
goto('/');
|
||||
}
|
||||
} catch (err) {
|
||||
errorMessage = 'An error occurred. Please try again.';
|
||||
} finally {
|
||||
isLoading = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex min-h-screen flex-col items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
|
||||
<div class="w-full max-w-md space-y-8">
|
||||
<div>
|
||||
<h2 class="mt-6 text-center text-3xl font-bold tracking-tight text-gray-900">Sign in to your account</h2>
|
||||
</div>
|
||||
|
||||
{#if errorMessage}
|
||||
<div class="rounded-md bg-red-50 p-4">
|
||||
<div class="flex">
|
||||
<div class="ml-3">
|
||||
<p class="text-sm font-medium text-red-800">{errorMessage}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<form class="mt-8 space-y-6" on:submit|preventDefault={handleSubmit}>
|
||||
<input type="hidden" name="remember" value="true" />
|
||||
<div class="-space-y-px rounded-md shadow-sm">
|
||||
<div>
|
||||
<label for="username" class="sr-only">Username</label>
|
||||
<input
|
||||
id="username"
|
||||
name="username"
|
||||
type="text"
|
||||
autocomplete="username"
|
||||
required
|
||||
bind:value={username}
|
||||
class="relative block w-full rounded-t-md border-0 py-1.5 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:z-10 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
|
||||
placeholder="Username"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label for="password" class="sr-only">Password</label>
|
||||
<input
|
||||
id="password"
|
||||
name="password"
|
||||
type="password"
|
||||
autocomplete="current-password"
|
||||
required
|
||||
bind:value={password}
|
||||
class="relative block w-full rounded-b-md border-0 py-1.5 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:z-10 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
|
||||
placeholder="Password"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isLoading}
|
||||
class="group relative flex w-full justify-center rounded-md bg-indigo-600 py-2 px-3 text-sm font-semibold text-white hover:bg-indigo-700 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
|
||||
>
|
||||
{#if isLoading}
|
||||
<svg class="animate-spin -ml-1 mr-2 h-4 w-4 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||
</svg>
|
||||
Signing in...
|
||||
{:else}
|
||||
Sign in
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,105 +0,0 @@
|
||||
<script lang='ts'>
|
||||
import "../../../app.postcss";
|
||||
import { onMount } from "svelte";
|
||||
import { PUBLIC_BASE_URL } from "$env/static/public";
|
||||
import type { company } from '$lib/types/types'
|
||||
|
||||
export let company_data: company;
|
||||
|
||||
|
||||
let company_name: string = '';
|
||||
let tel_number: string = '';
|
||||
|
||||
onMount(async () => {
|
||||
await fetch(PUBLIC_BASE_URL + "/info/company", {
|
||||
method: "get",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((result) => (company_data = result));
|
||||
|
||||
if (company_data["ok"] == true) {
|
||||
company_name = company_data["company_name"];
|
||||
tel_number = company_data["company_phone_number"];
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
<title>Our Oil at Auburn Oil </title>
|
||||
<div class="bg-secondary px-10">
|
||||
<div
|
||||
class="max-w-7xl justify-center py-5 mx-auto font-bold text-white"
|
||||
>
|
||||
<h1>Our Oil</h1>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="max-w-7xl mx-auto px-10">
|
||||
<div class="grid grid-cols-12 max-w-7xl gap-5">
|
||||
<div class="col-span-12 text-2xl text-bold"></div>
|
||||
<div class="col-span-12 md:col-span-6 mb-20">
|
||||
<div class="col-span-12 mb-5 font-bold text-xl text-primary">
|
||||
Our Oil Wont Ruin your heating system!
|
||||
</div>
|
||||
<div class="col-span-12 text-lg">
|
||||
We sell the best heating oil that is legally allowed on the market.
|
||||
The government currently requires 5% bio mix be added before it is sold to heating companies and the public.
|
||||
</div>
|
||||
<div class="col-span-12 mb-5 text-2xl font-bold mt-10 text-primary">
|
||||
The best oil in your Tank
|
||||
</div>
|
||||
<div class="col-span-12 mb-10">
|
||||
<ul>
|
||||
<div class="flex gap-5">
|
||||
|
||||
<li class=" font-bold text-orange-600">2-5% biodiesel (B2–B5) is Bioheat® fuel (Our Oil)</li>
|
||||
</div>
|
||||
<div class="flex gap-5">
|
||||
<li class=" font-bold">
|
||||
5-20% biodiesel (B5–B20) is Bioheat Plus® fuel
|
||||
</li>
|
||||
</div>
|
||||
<div class="flex gap-5">
|
||||
<li class=" font-bold">
|
||||
20% biodiesel and above (B20+) is Bioheat Super Plus®
|
||||
</li>
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 mb-10">
|
||||
<div class="text-2xl font-bold mt-10 text-error mb-5">
|
||||
Symptoms your oil company is selling you bad oil. Some companies are 50% plus bio in your oil!
|
||||
</div>
|
||||
<ul class="text-lg">
|
||||
<li>- System needs filters frequently</li>
|
||||
<li>- Furnace has bad flame and doesnt produce high heat</li>
|
||||
<li>- System is clogged</li>
|
||||
<li>- Tank goes bad all of a sudden!</li>
|
||||
<li>- Frozen lines in the winter. Bio brings the freezing point much higher!</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-span-12 mb-5 text-2xl font-bold mt-10 text-primary">
|
||||
We sell better heating oil at a cheaper price.
|
||||
</div>
|
||||
<div class="col-span-12 mb-5 font-bold text-xl">
|
||||
See the slime? Imagine that all inside your tank and equipment!
|
||||
</div>
|
||||
<div class="col-span-12 mb-5 font-bold text-xl text-center">
|
||||
Thats a bio filled system :(
|
||||
</div>
|
||||
|
||||
<div class="col-span-12">
|
||||
<img class="w-full p-0 m-0" src="/images/biobad.png" alt="Oil burner cleaning" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-12 md:col-span-6">
|
||||
<img class="w-full p-0 m-0" src="/images/oildelivery.jpg" alt="Delivering Oil" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
144
src/routes/(app)/register/+page.svelte
Executable file
144
src/routes/(app)/register/+page.svelte
Executable file
@@ -0,0 +1,144 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
import type { RegisterRequest } from '$lib/types/types';
|
||||
|
||||
let email = '';
|
||||
let username = '';
|
||||
let password = '';
|
||||
let confirmPassword = '';
|
||||
let errorMessage = '';
|
||||
let isLoading = false;
|
||||
|
||||
async function handleSubmit() {
|
||||
if (password !== confirmPassword) {
|
||||
errorMessage = 'Passwords do not match';
|
||||
return;
|
||||
}
|
||||
|
||||
const registerData: RegisterRequest = {
|
||||
email,
|
||||
username,
|
||||
password
|
||||
};
|
||||
|
||||
isLoading = true;
|
||||
errorMessage = '';
|
||||
|
||||
try {
|
||||
const response = await fetch('/register', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(registerData)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json();
|
||||
errorMessage = errorData.error || 'Registration failed';
|
||||
} else {
|
||||
// Redirect to login or home page after successful registration
|
||||
goto('/login');
|
||||
}
|
||||
} catch (err) {
|
||||
errorMessage = 'An error occurred. Please try again.';
|
||||
} finally {
|
||||
isLoading = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex min-h-screen flex-col items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
|
||||
<div class="w-full max-w-md space-y-8">
|
||||
<div>
|
||||
<h2 class="mt-6 text-center text-3xl font-bold tracking-tight text-gray-900">Create your account</h2>
|
||||
</div>
|
||||
|
||||
{#if errorMessage}
|
||||
<div class="rounded-md bg-red-50 p-4">
|
||||
<div class="flex">
|
||||
<div class="ml-3">
|
||||
<p class="text-sm font-medium text-red-800">{errorMessage}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<form class="mt-8 space-y-6" on:submit|preventDefault={handleSubmit}>
|
||||
<input type="hidden" name="remember" value="true" />
|
||||
<div class="-space-y-px rounded-md shadow-sm">
|
||||
<div>
|
||||
<label for="email-address" class="sr-only">Email address</label>
|
||||
<input
|
||||
id="email-address"
|
||||
name="email"
|
||||
type="email"
|
||||
autocomplete="email"
|
||||
required
|
||||
bind:value={email}
|
||||
class="relative block w-full rounded-t-md border-0 py-1.5 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:z-10 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
|
||||
placeholder="Email address"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label for="username" class="sr-only">Username</label>
|
||||
<input
|
||||
id="username"
|
||||
name="username"
|
||||
type="text"
|
||||
autocomplete="username"
|
||||
required
|
||||
bind:value={username}
|
||||
class="relative block w-full border-0 py-1.5 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:z-10 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
|
||||
placeholder="Username"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label for="password" class="sr-only">Password</label>
|
||||
<input
|
||||
id="password"
|
||||
name="password"
|
||||
type="password"
|
||||
autocomplete="new-password"
|
||||
required
|
||||
bind:value={password}
|
||||
class="relative block w-full border-0 py-1.5 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:z-10 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
|
||||
placeholder="Password"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label for="confirm-password" class="sr-only">Confirm Password</label>
|
||||
<input
|
||||
id="confirm-password"
|
||||
name="confirm-password"
|
||||
type="password"
|
||||
autocomplete="new-password"
|
||||
required
|
||||
bind:value={confirmPassword}
|
||||
class="relative block w-full rounded-b-md border-0 py-1.5 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:z-10 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
|
||||
placeholder="Confirm Password"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isLoading}
|
||||
class="group relative flex w-full justify-center rounded-md bg-indigo-600 py-2 px-3 text-sm font-semibold text-white hover:bg-indigo-700 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
|
||||
>
|
||||
{#if isLoading}
|
||||
<svg class="animate-spin -ml-1 mr-2 h-4 w-4 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||
</svg>
|
||||
Registering...
|
||||
{:else}
|
||||
Register
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,105 +0,0 @@
|
||||
<script lang='ts'>
|
||||
import "../../../app.postcss";
|
||||
import { onMount } from "svelte";
|
||||
import { PUBLIC_BASE_URL } from "$env/static/public";
|
||||
import type { company } from '$lib/types/types'
|
||||
|
||||
export let company_data: company;
|
||||
|
||||
|
||||
let company_name: string = '';
|
||||
let tel_number: string = '';
|
||||
|
||||
onMount(async () => {
|
||||
await fetch(PUBLIC_BASE_URL + "/info/company", {
|
||||
method: "get",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((result) => (company_data = result));
|
||||
|
||||
if (company_data["ok"] == true) {
|
||||
company_name = company_data["company_name"];
|
||||
tel_number = company_data["company_phone_number"];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<title>Delivery towns and Map</title>
|
||||
|
||||
<div class="bg-secondary px-10">
|
||||
<div class="max-w-7xl justify-center py-5 mx-auto font-bold text-white">
|
||||
<h1>Delivery Area</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="h-auto">
|
||||
<div class="mx-auto p-5">
|
||||
<div class="grid grid-cols-12 ">
|
||||
<div class="col-span-12 py-5 ">
|
||||
<div class="font-bold text-secondary mx-auto text-center md:text-left">
|
||||
<h3>Serving these communites</h3>
|
||||
</div>
|
||||
<div class="font-bold text-xl bg-secondary text-primary h-10 mb-10">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-12 py-5 ">
|
||||
<div class="invisible md:visible h-0 md:h-auto flex gap-20 justify-center text-3xl">
|
||||
<div >
|
||||
<div class="text-2xl">Auburn</div>
|
||||
<div class="text-2xl">Millbury</div>
|
||||
<div class="text-2xl">Sutton</div>
|
||||
<div class="text-2xl">Oxford</div>
|
||||
<div class="text-2xl">North Oxford</div>
|
||||
<div class="text-2xl">Webster</div>
|
||||
<div class="text-2xl">Southbridge</div>
|
||||
<div class="text-2xl">Shrewsbury</div>
|
||||
<div class="text-2xl">Grafton</div>
|
||||
</div>
|
||||
<div >
|
||||
<div class="text-2xl">Dudley</div>
|
||||
<div class="text-2xl">Sutton</div>
|
||||
<div class="text-2xl">Charlton</div>
|
||||
<div class="text-2xl">Leicester</div>
|
||||
<div class="text-2xl">Cherry Valley</div>
|
||||
<div class="text-2xl">Rochdale</div>
|
||||
<div class="text-2xl">Spencer</div>
|
||||
<div class="text-2xl">Southbridge</div>
|
||||
<div class="text-2xl">Worcester</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="visible sm:visible md:invisible h-auto sm:h-auto md:h-0">
|
||||
<div class="text-center">
|
||||
<div class="text-2xl">Auburn</div>
|
||||
<div class="text-2xl">Millbury</div>
|
||||
<div class="text-2xl">Sutton</div>
|
||||
<div class="text-2xl">Oxford</div>
|
||||
<div class="text-2xl">North Oxford</div>
|
||||
<div class="text-2xl">Webster</div>
|
||||
<div class="text-2xl">Southbridge</div>
|
||||
<div class="text-2xl">Shrewsbury</div>
|
||||
<div class="text-2xl">Grafton</div>
|
||||
<div class="text-2xl">Dudley</div>
|
||||
<div class="text-2xl">Charlton</div>
|
||||
<div class="text-2xl">Leicester</div>
|
||||
<div class="text-2xl">Cherry Valley</div>
|
||||
<div class="text-2xl">Rochdale</div>
|
||||
<div class="text-2xl">Spencer</div>
|
||||
<div class="text-2xl">Sutton</div>
|
||||
<div class="text-2xl">Southbridge</div>
|
||||
<div class="text-2xl">Worcester</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-12 py-5 ">
|
||||
<div class="flex justify-center items-center md:h-auto">
|
||||
<img class="" src="/images/area.png" alt="Worcester County oil delivery">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
9
static/fonts.css
Executable file
9
static/fonts.css
Executable file
@@ -0,0 +1,9 @@
|
||||
@font-face {
|
||||
font-family: 'EnterS';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: url('/fonts/entsans.tff'); /* IE9 Compat Modes */
|
||||
src: local(''), url('/fonts/entsans.ttf') format('truetype'),
|
||||
/* Modern Browsers */ url('/fonts/entsans.ttf') format('truetype'),
|
||||
|
||||
}
|
||||
0
static/robots.txt
Normal file → Executable file
0
static/robots.txt
Normal file → Executable file
@@ -1,5 +1,5 @@
|
||||
import adapter from "@sveltejs/adapter-node";
|
||||
import { vitePreprocess } from "@sveltejs/kit/vite";
|
||||
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
{
|
||||
"extends": "./.svelte-kit/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
|
||||
Reference in New Issue
Block a user