This commit is contained in:
2025-06-08 13:21:49 -04:00
parent 942d341527
commit a4188c623d
21 changed files with 1254 additions and 1776 deletions

1567
package-lock.json generated Normal file → Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
{
"name": "auburnoil",
"name": "newenglandbio",
"version": "0.0.1",
"private": true,
"scripts": {

0
public/favicon.ico Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 318 B

After

Width:  |  Height:  |  Size: 318 B

0
public/robots.txt Normal file → Executable file
View File

0
src/favicon.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 318 B

After

Width:  |  Height:  |  Size: 318 B

113
src/lib/types/types.ts Normal file → Executable file
View 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;
}

View File

@@ -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>

View File

@@ -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>

View 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>

View 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}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View 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>

View File

@@ -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 (B2B5) is Bioheat® fuel (Our Oil)</li>
</div>
<div class="flex gap-5">
<li class=" font-bold">
5-20% biodiesel (B5B20) 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>

View 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>

View File

@@ -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
View 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
View File

View 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 = {

View File

@@ -1,4 +1,3 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {