Add new sections and update navigation in components

This commit is contained in:
Emil Gulamov 2024-06-29 03:37:38 +04:00
parent d81f8eb208
commit 0cecec1424
7 changed files with 821 additions and 0 deletions

View file

@ -0,0 +1,16 @@
---
// Import the necessary components from their respective component files
import LoginModal from "@components/ui/forms/LoginModal.astro";
import RegisterModal from "@components/ui/forms/RegisterModal.astro";
import RecoverModal from "@components/ui/forms/RecoverModal.astro";
import LoginBtn from "@components/ui/buttons/LoginBtn.astro";
---
<!-- Login Button -->
<LoginBtn />
<!-- Login Modal -->
<LoginModal />
<!-- Register Modal -->
<RegisterModal />
<!-- Password Recovery Modal -->
<RecoverModal />

View file

@ -0,0 +1,118 @@
---
// Import the necessary dependencies.
import AuthBtn from "@components/ui/buttons/AuthBtn.astro";
import ContactIconBlock from "@components/ui/blocks/ContactIconBlock.astro";
import TextInput from "@components/ui/forms/input/TextInput.astro";
import EmailContactInput from "@components/ui/forms/input/EmailContactInput.astro";
import PhoneInput from "@components/ui/forms/input/PhoneInput.astro";
import TextAreaInput from "@components/ui/forms/input/TextAreaInput.astro";
import Icon from "@components/ui/icons/Icon.astro";
// Define the variables that will be used in this component
const title: string = "Contact us";
const subTitle: string =
"Have questions or want to discuss a project? Reach out, and let's craft the perfect solution with our tools and services.";
const formTitle: string = "Fill in the form below";
const formSubTitle: string = "We'll get back to you in 1-2 business days.";
---
<!-- Contact Us -->
<section class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14">
<div class="mx-auto max-w-2xl lg:max-w-5xl">
<div class="text-center">
<h1
class="text-balance text-2xl font-bold tracking-tight text-neutral-800 dark:text-neutral-200 md:text-4xl md:leading-tight"
>
{title}
</h1>
<p class="mt-1 text-pretty text-neutral-600 dark:text-neutral-400">
{subTitle}
</p>
</div>
<div class="mt-12 grid items-center gap-6 lg:grid-cols-2 lg:gap-16">
<div class="flex flex-col rounded-xl p-4 sm:p-6 lg:p-8">
<h2
class="mb-8 text-xl font-bold text-neutral-700 dark:text-neutral-300"
>
{formTitle}
</h2>
<!-- Form for user input with various input fields.-->
<!-- Each field utilizes a different input component for the specific type of input (text, email, phone, and textarea)-->
<form>
<div class="grid gap-4">
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
<TextInput
id="hs-firstname-contacts"
label="First Name"
name="hs-firstname-contacts"
/>
<TextInput
id="hs-lastname-contacts"
label="Last Name"
name="hs-firstname-contacts"
/>
</div>
<EmailContactInput id="hs-email-contacts" />
<PhoneInput id="hs-phone-number" />
<TextAreaInput
id="hs-about-contacts"
label="Details"
name="hs-about-contacts"
/>
</div>
<div class="mt-4 grid">
<AuthBtn title="Send Message" />
</div>
<div class="mt-3 text-center">
<p class="text-sm text-neutral-600 dark:text-neutral-400">
{formSubTitle}
</p>
</div>
</form>
</div>
<!--ContactIconBlocks are used to display different methods of contacting, including visiting office, email, browsing knowledgebase, and FAQ.-->
<div class="divide-y divide-neutral-300 dark:divide-neutral-700">
<ContactIconBlock
heading="Knowledgebase"
content="Browse through all of our knowledgebase articles."
isLinkVisible={true}
linkTitle="Visit guides & tutorials"
linkURL="#"
isArrowVisible={true}
><Icon name="question" />
</ContactIconBlock>
<ContactIconBlock
heading="FAQ"
content="Explore our FAQ for quick, clear answers to common queries."
isLinkVisible={true}
linkTitle="Visit FAQ"
linkURL="#"
isArrowVisible={true}
><Icon name="chatBubble" />
</ContactIconBlock>
<ContactIconBlock
heading="Visit our office"
content="UK ScrewFast"
isAddressVisible={true}
addressContent="72 Union Terrace, E10 4PE London"
><Icon name="mapPin" />
</ContactIconBlock>
<ContactIconBlock
heading="Contact us by email"
content="Prefer the written word? Drop us an email at"
isLinkVisible={true}
linkTitle="support@screwfast.uk"
linkURL="#"
><Icon name="envelopeOpen" />
</ContactIconBlock>
</div>
</div>
</div>
</section>

View file

@ -0,0 +1,79 @@
---
// Import the necessary AccordionItem component and JSON data
import AccordionItem from "@components/ui/blocks/AccordionItem.astro";
// Define props from Astro
const { title, faqs } = Astro.props;
// Define TypeScript interface for props
interface Faq {
question: string;
answer: string;
}
interface FaqGroup {
subTitle?: string;
faqs: Faq[];
}
interface Props {
title: string;
faqs: FaqGroup;
}
// Define a helper function to generate ids dynamically.
const makeId = (base: any, index: any) => `${base}${index + 1}`;
---
<!-- Main container that holds all content. Customized for different viewport sizes. -->
<section
class="mx-auto max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
>
<div class="grid gap-10 md:grid-cols-5">
<div class="md:col-span-2">
<div class="max-w-xs">
<h2
class="text-2xl font-bold text-neutral-800 dark:text-neutral-200 md:text-4xl md:leading-tight"
>
<Fragment set:html={title} />
</h2>
<p class="mt-1 hidden text-neutral-600 dark:text-neutral-400 md:block">
{faqs.subTitle}
</p>
</div>
</div>
<!-- FAQ accordion items -->
<div class="md:col-span-3">
<div
class="hs-accordion-group divide-y divide-neutral-200 dark:divide-neutral-700"
>
{
faqs.faqs.map((question, i) => {
// Generate ids dynamically for each FAQ accordion item.
let id = makeId(
"hs-basic-with-title-and-arrow-stretched-heading-",
i
);
let collapseId = makeId(
"hs-basic-with-title-and-arrow-stretched-collapse",
i
);
return (
<AccordionItem
{...question}
id={id}
collapseId={collapseId}
first={i === 0}
/>
);
})
}
</div>
</div>
</div>
</section>
<!--Import the necessary Accordion plugin-->
<!--https://preline.co/plugins/html/accordion.html-->
<script>
import "@preline/accordion/index.js";
</script>

View file

@ -0,0 +1,117 @@
---
// Import the necessary dependencies
import FooterSocialLink from "@components/ui/links/FooterSocialLink.astro";
import EmailFooterInput from "@components/ui/forms/input/EmailFooterInput.astro";
import enStrings from "@utils/navigation.ts";
import frStrings from "@utils/fr/navigation.ts";
import Icon from "@components/ui/icons/Icon.astro";
import BrandLogo from "@components/BrandLogo.astro";
import { SITE } from "@data/constants";
// Select the correct translation based on the page's lang prop:
const strings = Astro.currentLocale === "fr" ? frStrings : enStrings;
// Define the variables that will be used in this component
const sectionThreeTitle: string = Astro.currentLocale === "fr" ? "Rester à jour" : "Stay up to date";
const sectionThreeContent: string = Astro.currentLocale === "fr" ? "Restez informé des derniers outils et des offres exclusives." :
"Stay updated with the latest tools and exclusive deals.";
const crafted: string = Astro.currentLocale === "fr" ? "Fabriqué par" : "Crafted by";
---
<footer class="w-full bg-neutral-300 dark:bg-neutral-900">
<div
class="mx-auto w-full max-w-[85rem] px-4 py-10 sm:px-6 lg:px-16 lg:pt-20 2xl:max-w-screen-2xl"
>
<div class="grid grid-cols-2 gap-6 md:grid-cols-4 lg:grid-cols-5">
<div class="col-span-full lg:col-span-1">
<!-- Brand Logo -->
<BrandLogo class="h-auto w-32" />
</div>
<!-- An array of links for Product and Company sections -->
{
strings.footerLinks.map((section) => (
<div class="col-span-1">
<h3 class="font-bold text-neutral-800 dark:text-neutral-200">
{section.section}
</h3>
<ul class="mt-3 grid space-y-3">
{section.links.map((link, index) => (
<li>
<a
href={link.url}
class="inline-flex gap-x-2 rounded-lg text-neutral-600 outline-none ring-zinc-500 transition duration-300 hover:text-neutral-500 focus-visible:ring dark:text-neutral-400 dark:ring-zinc-200 dark:hover:text-neutral-300 dark:focus:outline-none"
>
{link.name}
</a>
{section.section === "Company" && index === 2 ? (
<span class="ms-1 inline rounded-lg bg-orange-500 px-2 py-1 text-xs font-bold text-neutral-50">
We're hiring!
</span>
) : null}
</li>
))}
</ul>
</div>
))
}
<div class="col-span-2">
<h3 class="font-bold text-neutral-800 dark:text-neutral-200">
{sectionThreeTitle}
</h3>
<form>
<EmailFooterInput />
<p class="mt-3 text-sm text-neutral-600 dark:text-neutral-400">
{sectionThreeContent}
</p>
</form>
</div>
</div>
<div
class="mt-9 grid gap-y-2 sm:mt-12 sm:flex sm:items-center sm:justify-between sm:gap-y-0"
>
<div class="flex items-center justify-between">
<p class="text-sm text-neutral-600 dark:text-neutral-400">
© <span id="current-year"></span> {SITE.title}. {crafted}
<a
class="rounded-lg font-medium underline underline-offset-2 outline-none ring-zinc-500 transition duration-300 hover:text-neutral-700 hover:decoration-dashed focus:outline-none focus-visible:ring dark:ring-zinc-200 dark:hover:text-neutral-300"
href="https://sobstvennoai.dev"
target="_blank"
rel="noopener noreferrer">sobstvennoAI</a
>.
</p>
</div>
<!-- Social Brands -->
<div>
<FooterSocialLink url={strings.socialLinks.facebook}
><Icon name="facebookFooter" />
</FooterSocialLink>
<FooterSocialLink url={strings.socialLinks.x}
><Icon name="xFooter" /></FooterSocialLink
>
<FooterSocialLink url={strings.socialLinks.github}
><Icon name="githubFooter" />
</FooterSocialLink>
<FooterSocialLink url={strings.socialLinks.google}
><Icon name="googleFooter" />
</FooterSocialLink>
<FooterSocialLink url={strings.socialLinks.slack}
><Icon name="slackFooter" />
</FooterSocialLink>
</div>
</div>
<script>
const year = new Date().getFullYear();
const element = document.getElementById("current-year");
element!.innerText = year.toString();
</script>
</div>
</footer>

View file

@ -0,0 +1,214 @@
---
//Import relevant dependencies
import ThemeIcon from "@components/ThemeIcon.astro";
import NavLink from "@components/ui/links/NavLink.astro";
import Authentication from "../misc/Authentication.astro";
import enStrings from "@utils/navigation.ts";
import frStrings from "@utils/fr/navigation.ts";
import BrandLogo from "@components/BrandLogo.astro";
import LanguagePicker from "@components/ui/LanguagePicker.astro";
// Select the correct translation based on the page's lang prop:
const strings = Astro.currentLocale === "fr" ? frStrings : enStrings;
const homeUrl = Astro.currentLocale === "fr" ? "/fr" : "/";
---
<!-- Main header component -->
<header
class="sticky inset-x-0 top-4 z-50 flex w-full flex-wrap text-sm md:flex-nowrap md:justify-start"
>
<!-- Navigation container -->
<nav
class="relative mx-2 w-full rounded-[36px] border border-yellow-100/40 bg-yellow-50/60 px-4 py-3 backdrop-blur-md dark:border-neutral-700/40 dark:bg-neutral-800/80 dark:backdrop-blur-md md:flex md:items-center md:justify-between md:px-6 md:py-0 lg:px-8 xl:mx-auto"
aria-label="Global"
>
<div class="flex items-center justify-between">
<!-- Brand logo -->
<a
class="flex-none rounded-lg text-xl font-bold outline-none ring-zinc-500 focus-visible:ring dark:ring-zinc-200 dark:focus:outline-none"
href={homeUrl}
aria-label="Brand"
>
<BrandLogo class="h-auto w-24" />
</a>
<!-- Collapse toggle for smaller screens -->
<div class="ml-auto mr-5 md:hidden">
<button
type="button"
class="hs-collapse-toggle flex h-8 w-8 items-center justify-center rounded-full text-sm font-bold text-neutral-600 transition duration-300 hover:bg-neutral-200 disabled:pointer-events-none disabled:opacity-50 dark:text-neutral-400 dark:hover:bg-neutral-700 dark:focus:outline-none"
data-hs-collapse="#navbar-collapse-with-animation"
aria-controls="navbar-collapse-with-animation"
aria-label="Toggle navigation"
>
<svg
class="h-[1.25rem] w-[1.25rem] flex-shrink-0 hs-collapse-open:hidden"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<line x1="3" x2="21" y1="6" y2="6"></line>
<line x1="3" x2="21" y1="12" y2="12"></line>
<line x1="3" x2="21" y1="18" y2="18"></line>
</svg>
<svg
class="hidden h-[1.25rem] w-[1.25rem] flex-shrink-0 hs-collapse-open:block"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M18 6 6 18"></path>
<path d="m6 6 12 12"></path>
</svg>
</button>
</div>
<!-- ThemeIcon component specifically for smaller screens -->
<span class="inline-block md:hidden">
<ThemeIcon />
</span>
</div>
<!-- Contains navigation links -->
<div
id="navbar-collapse-with-animation"
class="hs-collapse hidden grow basis-full overflow-hidden transition-all duration-300 md:block"
>
<!-- Navigation links container -->
<div
class="mt-5 flex flex-col gap-x-0 gap-y-4 md:mt-0 md:flex-row md:items-center md:justify-end md:gap-x-4 lg:gap-x-7 md:gap-y-0 md:ps-7"
>
<!-- Navigation links and Authentication component -->
{strings.navBarLinks.map(link => (
<NavLink url={link.url} name={link.name} />
))}
<Authentication />
<LanguagePicker />
<!-- ThemeIcon component specifically for larger screens -->
<span class="hidden md:inline-block">
<ThemeIcon />
</span>
</div>
</div>
</nav>
</header>
<!-- Theme Appearance script to manage light/dark modes -->
<script is:inline>
const HSThemeAppearance = {
init() {
const defaultTheme = "default";
let theme = localStorage.getItem("hs_theme") || defaultTheme;
if (document.querySelector("html").classList.contains("dark")) return;
this.setAppearance(theme);
},
_resetStylesOnLoad() {
const $resetStyles = document.createElement("style");
$resetStyles.innerText = `*{transition: unset !important;}`;
$resetStyles.setAttribute("data-hs-appearance-onload-styles", "");
document.head.appendChild($resetStyles);
return $resetStyles;
},
setAppearance(theme, saveInStore = true, dispatchEvent = true) {
const $resetStylesEl = this._resetStylesOnLoad();
if (saveInStore) {
localStorage.setItem("hs_theme", theme);
}
if (theme === "auto") {
theme = window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "default";
}
document.querySelector("html").classList.remove("dark");
document.querySelector("html").classList.remove("default");
document.querySelector("html").classList.remove("auto");
document
.querySelector("html")
.classList.add(this.getOriginalAppearance());
setTimeout(() => {
$resetStylesEl.remove();
});
if (dispatchEvent) {
window.dispatchEvent(
new CustomEvent("on-hs-appearance-change", { detail: theme }),
);
}
},
getAppearance() {
let theme = this.getOriginalAppearance();
if (theme === "auto") {
theme = window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "default";
}
return theme;
},
getOriginalAppearance() {
const defaultTheme = "default";
return localStorage.getItem("hs_theme") || defaultTheme;
},
};
HSThemeAppearance.init();
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", () => {
if (HSThemeAppearance.getOriginalAppearance() === "auto") {
HSThemeAppearance.setAppearance("auto", false);
}
});
window.addEventListener("load", () => {
const $clickableThemes = document.querySelectorAll(
"[data-hs-theme-click-value]",
);
const $switchableThemes = document.querySelectorAll(
"[data-hs-theme-switch]",
);
$clickableThemes.forEach(($item) => {
$item.addEventListener("click", () =>
HSThemeAppearance.setAppearance(
$item.getAttribute("data-hs-theme-click-value"),
true,
$item,
),
);
});
$switchableThemes.forEach(($item) => {
$item.addEventListener("change", (e) => {
HSThemeAppearance.setAppearance(e.target.checked ? "dark" : "default");
});
$item.checked = HSThemeAppearance.getAppearance() === "dark";
});
window.addEventListener("on-hs-appearance-change", (e) => {
$switchableThemes.forEach(($item) => {
$item.checked = e.detail === "dark";
});
});
});
</script>
<!--Import the necessary Collapse and Overlay plugins-->
<!--https://preline.co/plugins/html/collapse.html-->
<!--https://preline.co/plugins/html/overlay.html-->
<script>
import "@preline/collapse/index.js";
import "@preline/overlay/index.js";
</script>

View file

@ -0,0 +1,223 @@
---
//Import relevant dependencies
import ThemeIcon from "@components/ThemeIcon.astro";
import NavLink from "@components/ui/links/NavLink.astro";
import MegaMenuLink from "@components/ui/links/MegaMenuLink.astro";
import Authentication from "../misc/Authentication.astro";
import enStrings from "@utils/navigation.ts";
import frStrings from "@utils/fr/navigation.ts";
import BrandLogo from "@components/BrandLogo.astro";
import LanguagePicker from "@components/ui/LanguagePicker.astro";
// Select the correct translation based on the page's lang prop:
const strings = Astro.currentLocale === "fr" ? frStrings : enStrings;
const homeUrl = Astro.currentLocale === "fr" ? "/fr" : "/";
---
<!-- Main header component -->
<header
class="sticky inset-x-0 top-4 z-50 flex w-full flex-wrap text-sm md:flex-nowrap md:justify-start"
>
<!-- Navigation container -->
<nav
class="relative mx-2 w-full rounded-[36px] border border-yellow-100/40 bg-yellow-50/60 px-4 py-3 backdrop-blur-md dark:border-neutral-700/40 dark:bg-neutral-800/80 dark:backdrop-blur-md md:flex md:items-center md:justify-between md:px-6 md:py-0 lg:px-8 xl:mx-auto"
aria-label="Global"
>
<div class="flex items-center justify-between">
<!-- Brand logo -->
<a
class="flex-none rounded-lg text-xl font-bold outline-none ring-zinc-500 focus-visible:ring dark:ring-zinc-200 dark:focus:outline-none"
href={homeUrl}
aria-label="Brand"
>
<BrandLogo class="h-auto w-24" />
</a>
<!-- Collapse toggle for smaller screens -->
<div class="ml-auto mr-5 md:hidden">
<button
type="button"
class="hs-collapse-toggle flex h-8 w-8 items-center justify-center rounded-full text-sm font-bold text-neutral-600 transition duration-300 hover:bg-neutral-200 disabled:pointer-events-none disabled:opacity-50 dark:text-neutral-400 dark:hover:bg-neutral-700 dark:focus:outline-none"
data-hs-collapse="#navbar-collapse-with-animation"
aria-controls="navbar-collapse-with-animation"
aria-label="Toggle navigation"
>
<svg
class="h-[1.25rem] w-[1.25rem] flex-shrink-0 hs-collapse-open:hidden"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<line x1="3" x2="21" y1="6" y2="6"></line>
<line x1="3" x2="21" y1="12" y2="12"></line>
<line x1="3" x2="21" y1="18" y2="18"></line>
</svg>
<svg
class="hidden h-[1.25rem] w-[1.25rem] flex-shrink-0 hs-collapse-open:block"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M18 6 6 18"></path>
<path d="m6 6 12 12"></path>
</svg>
</button>
</div>
<!-- ThemeIcon component specifically for smaller screens -->
<span class="inline-block md:hidden">
<ThemeIcon />
</span>
</div>
<!-- Contains navigation links -->
<div
id="navbar-collapse-with-animation"
class="hs-collapse hidden grow basis-full overflow-hidden transition-all duration-300 md:block"
>
<!-- Navigation links container -->
<div
class="mt-5 flex flex-col gap-x-0 gap-y-4 md:mt-0 md:flex-row md:items-center md:justify-end md:gap-x-4 md:gap-y-0 md:ps-7 lg:gap-x-7"
>
<!-- Navigation links and Authentication component -->
{
strings.navBarLinks.map((link) => {
if (link.name === "Services") {
return <MegaMenuLink />;
} else {
return <NavLink url={link.url} name={link.name} />;
}
})
}
<Authentication />
<LanguagePicker />
<!-- ThemeIcon component specifically for larger screens -->
<span class="hidden md:inline-block">
<ThemeIcon />
</span>
</div>
</div>
</nav>
</header>
<!-- Theme Appearance script to manage light/dark modes -->
<script is:inline>
const HSThemeAppearance = {
init() {
const defaultTheme = "default";
let theme = localStorage.getItem("hs_theme") || defaultTheme;
if (document.querySelector("html").classList.contains("dark")) return;
this.setAppearance(theme);
},
_resetStylesOnLoad() {
const $resetStyles = document.createElement("style");
$resetStyles.innerText = `*{transition: unset !important;}`;
$resetStyles.setAttribute("data-hs-appearance-onload-styles", "");
document.head.appendChild($resetStyles);
return $resetStyles;
},
setAppearance(theme, saveInStore = true, dispatchEvent = true) {
const $resetStylesEl = this._resetStylesOnLoad();
if (saveInStore) {
localStorage.setItem("hs_theme", theme);
}
if (theme === "auto") {
theme = window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "default";
}
document.querySelector("html").classList.remove("dark");
document.querySelector("html").classList.remove("default");
document.querySelector("html").classList.remove("auto");
document
.querySelector("html")
.classList.add(this.getOriginalAppearance());
setTimeout(() => {
$resetStylesEl.remove();
});
if (dispatchEvent) {
window.dispatchEvent(
new CustomEvent("on-hs-appearance-change", { detail: theme })
);
}
},
getAppearance() {
let theme = this.getOriginalAppearance();
if (theme === "auto") {
theme = window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "default";
}
return theme;
},
getOriginalAppearance() {
const defaultTheme = "default";
return localStorage.getItem("hs_theme") || defaultTheme;
},
};
HSThemeAppearance.init();
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", () => {
if (HSThemeAppearance.getOriginalAppearance() === "auto") {
HSThemeAppearance.setAppearance("auto", false);
}
});
window.addEventListener("load", () => {
const $clickableThemes = document.querySelectorAll(
"[data-hs-theme-click-value]"
);
const $switchableThemes = document.querySelectorAll(
"[data-hs-theme-switch]"
);
$clickableThemes.forEach(($item) => {
$item.addEventListener("click", () =>
HSThemeAppearance.setAppearance(
$item.getAttribute("data-hs-theme-click-value"),
true,
$item
)
);
});
$switchableThemes.forEach(($item) => {
$item.addEventListener("change", (e) => {
HSThemeAppearance.setAppearance(e.target.checked ? "dark" : "default");
});
$item.checked = HSThemeAppearance.getAppearance() === "dark";
});
window.addEventListener("on-hs-appearance-change", (e) => {
$switchableThemes.forEach(($item) => {
$item.checked = e.detail === "dark";
});
});
});
</script>
<!--Import the necessary Collapse and Overlay plugins-->
<!--https://preline.co/plugins/html/collapse.html-->
<!--https://preline.co/plugins/html/overlay.html-->
<!--https://preline.co/plugins/html/dropdown.html-->
<script>
import "@preline/collapse/index.js";
import "@preline/overlay/index.js";
import "@preline/dropdown/index.js";
</script>

View file

@ -0,0 +1,54 @@
// Define data structures for services and success stories
export const servicesData = [
{
title: "Explore Advice and Explanations",
description:
"Dive deep into helpful guides and explanations for all of ScrewFast's features",
icon: "guides",
url: "#",
},
{
title: "Discover Integrations",
description:
"Supercharge Your Workflow. Seamless integrations with all your favorite tools",
icon: "puzzle",
url: "#",
},
{
title: "Expert Services",
description: "Go beyond tools with ScrewFast's expert services",
icon: "rocket",
url: "#",
},
{
title: "Cutting-Edge Tools",
description:
"Build Smarter, Faster. Experience next-level efficiency with ScrewFast's cutting-edge construction tools",
icon: "hammer",
url: "#",
},
{
title: "Simple Plans",
description:
"Boost your efficiency with ScrewFast's straightforward, value-driven plans",
icon: "sparks",
url: "#",
},
{
title: "Community Forum",
description: "Learn, share, and connect with other ScrewFast users",
icon: "community",
url: "#",
},
];
export const successStoriesData = [
{
image:
"https://images.unsplash.com/photo-1544005313-94ddf0286df2?q=80&w=1376&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D8&auto=format&fit=facearea&facepad=2&w=320&h=320&q=80",
alt: "Image Description",
description:
"See how ScrewFast has empowered businesses of all sizes to achieve outstanding results.",
learnMoreUrl: "#",
},
];