commit
a8a1fe5d53
70
package-lock.json
generated
70
package-lock.json
generated
@ -18,10 +18,12 @@
|
||||
"animejs": "^3.2.2",
|
||||
"bootstrap": "^5.1.3",
|
||||
"dayjs": "^1.11.13",
|
||||
"framer-motion": "^12.4.13",
|
||||
"graphql": "^16.10.0",
|
||||
"imagesloaded": "^5.0.0",
|
||||
"isotope-layout": "^3.0.6",
|
||||
"jarallax": "^2.2.1",
|
||||
"motion": "^12.4.13",
|
||||
"next": "15.2.0-canary.30",
|
||||
"payload": "^3.20.0",
|
||||
"photoswipe": "^5.4.4",
|
||||
@ -8092,6 +8094,33 @@
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/framer-motion": {
|
||||
"version": "12.4.13",
|
||||
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.4.13.tgz",
|
||||
"integrity": "sha512-JHSXIdL7WOTCSEb2UUurHURV85pWTn6UIg+iWLBhH5SFndbjni8CEQcxwsBwOs3RHZ83TkE4xoxb9cHsFPY9yQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"motion-dom": "^12.4.11",
|
||||
"motion-utils": "^12.4.10",
|
||||
"tslib": "^2.4.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emotion/is-prop-valid": "*",
|
||||
"react": "^18.0.0 || ^19.0.0",
|
||||
"react-dom": "^18.0.0 || ^19.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@emotion/is-prop-valid": {
|
||||
"optional": true
|
||||
},
|
||||
"react": {
|
||||
"optional": true
|
||||
},
|
||||
"react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
@ -10289,6 +10318,47 @@
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/motion": {
|
||||
"version": "12.4.13",
|
||||
"resolved": "https://registry.npmjs.org/motion/-/motion-12.4.13.tgz",
|
||||
"integrity": "sha512-8ehpE6Sd8ack6jLLzweW6RwCBQoASf+yVu8aUPFNKHsJIVejJaBPGsMiswcpfzHeCusZ/ztNIKbgoEn7ruJaOw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"framer-motion": "^12.4.13",
|
||||
"tslib": "^2.4.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emotion/is-prop-valid": "*",
|
||||
"react": "^18.0.0 || ^19.0.0",
|
||||
"react-dom": "^18.0.0 || ^19.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@emotion/is-prop-valid": {
|
||||
"optional": true
|
||||
},
|
||||
"react": {
|
||||
"optional": true
|
||||
},
|
||||
"react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/motion-dom": {
|
||||
"version": "12.4.11",
|
||||
"resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.4.11.tgz",
|
||||
"integrity": "sha512-wstlyV3pktgFjqsjbXMo1NX9hQD9XTVqxQNvfc+FREAgxr3GVzgWIEKvbyyNlki3J1jmmh+et9X3aCKeqFPcxA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"motion-utils": "^12.4.10"
|
||||
}
|
||||
},
|
||||
"node_modules/motion-utils": {
|
||||
"version": "12.4.10",
|
||||
"resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.4.10.tgz",
|
||||
"integrity": "sha512-NPwZd94V013SwRf++jMrk2+HEBgPkeIE2RiOzhAuuQlqxMJPkKt/LXVh6Upl+iN8oarSGD2dlY5/bqgsYXDABA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
|
@ -14,6 +14,7 @@
|
||||
"tsc": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@next/third-parties": "^15.2.2",
|
||||
"@payloadcms/db-postgres": "^3.20.0",
|
||||
"@payloadcms/next": "^3.20.0",
|
||||
"@payloadcms/payload-cloud": "^3.20.0",
|
||||
@ -24,10 +25,12 @@
|
||||
"animejs": "^3.2.2",
|
||||
"bootstrap": "^5.1.3",
|
||||
"dayjs": "^1.11.13",
|
||||
"framer-motion": "^12.4.13",
|
||||
"graphql": "^16.10.0",
|
||||
"imagesloaded": "^5.0.0",
|
||||
"isotope-layout": "^3.0.6",
|
||||
"jarallax": "^2.2.1",
|
||||
"motion": "^12.4.13",
|
||||
"next": "15.2.0-canary.30",
|
||||
"payload": "^3.20.0",
|
||||
"photoswipe": "^5.4.4",
|
||||
|
17
public/assets/css/bootstrap.min.css
vendored
17
public/assets/css/bootstrap.min.css
vendored
@ -47,8 +47,9 @@
|
||||
--bs-black-rgb: 0, 0, 0;
|
||||
--bs-body-color-rgb: 33, 37, 41;
|
||||
--bs-body-bg-rgb: 255, 255, 255;
|
||||
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans",
|
||||
"Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
--bs-font-sans-serif:
|
||||
system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif,
|
||||
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
||||
--bs-body-font-family: var(--bs-font-sans-serif);
|
||||
@ -70,7 +71,6 @@
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: var(--bs-body-font-family);
|
||||
font-size: var(--bs-body-font-size);
|
||||
font-weight: var(--bs-body-font-weight);
|
||||
line-height: var(--bs-body-line-height);
|
||||
@ -172,10 +172,7 @@ address {
|
||||
font-style: normal;
|
||||
line-height: inherit;
|
||||
}
|
||||
ol,
|
||||
ul {
|
||||
padding-left: 2rem;
|
||||
}
|
||||
|
||||
dl,
|
||||
ol,
|
||||
ul {
|
||||
@ -2535,7 +2532,8 @@ textarea.form-control.is-valid {
|
||||
.was-validated .form-select:valid:not([multiple]):not([size]),
|
||||
.was-validated .form-select:valid:not([multiple])[size="1"] {
|
||||
padding-right: 4.125rem;
|
||||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),
|
||||
background-image:
|
||||
url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),
|
||||
url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
|
||||
background-position:
|
||||
right 0.75rem center,
|
||||
@ -2634,7 +2632,8 @@ textarea.form-control.is-invalid {
|
||||
.was-validated .form-select:invalid:not([multiple]):not([size]),
|
||||
.was-validated .form-select:invalid:not([multiple])[size="1"] {
|
||||
padding-right: 4.125rem;
|
||||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),
|
||||
background-image:
|
||||
url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),
|
||||
url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");
|
||||
background-position:
|
||||
right 0.75rem center,
|
||||
|
@ -20,13 +20,12 @@
|
||||
.dark .light-mode-logo {
|
||||
display: none;
|
||||
}
|
||||
@media (min-width: 1025px) {
|
||||
/* @media (min-width: 1025px) {
|
||||
.mn-has-sub:hover + *,
|
||||
.mn-has-sub + *:hover {
|
||||
display: block !important;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
.fadeInText {
|
||||
animation: animationFadeText 0.5s linear 0s 1;
|
||||
@ -87,7 +86,7 @@ a {
|
||||
}
|
||||
|
||||
.mn-sub {
|
||||
transition: max-height 0.3s ease-in-out;
|
||||
transition: max-height;
|
||||
}
|
||||
|
||||
.mn-sub.open {
|
||||
|
@ -1,6 +1,4 @@
|
||||
.theme-slick {
|
||||
--font-global: "Plus Jakarta Sans", sans-serif;
|
||||
--font-alt: "Plus Jakarta Sans", sans-serif;
|
||||
--section-padding-y: 50px;
|
||||
--color-teal-1: #64b3b4;
|
||||
--color-dark-1: #1e2432;
|
||||
@ -66,14 +64,15 @@
|
||||
--gradient-gray-light-1: linear-gradient(0deg, #f7f9fc 0%, #fff 100%);
|
||||
--gradient-gray-light-2: linear-gradient(0deg, #fff 0%, #f7f9fc 100%);
|
||||
--border-radius-default: 10px;
|
||||
--box-shadow: 0px 5px 10px 0px rgba(30, 36, 50, 0.05), 0px 1px 1px 0px rgba(30, 36, 50, 0.03),
|
||||
--box-shadow:
|
||||
0px 5px 10px 0px rgba(30, 36, 50, 0.05), 0px 1px 1px 0px rgba(30, 36, 50, 0.03),
|
||||
0px 3px 5px 0px rgba(30, 36, 50, 0.03);
|
||||
--box-shadow-strong: 0px 5px 10px 0px rgba(30, 36, 50, 0.08), 0px 1px 1px 0px rgba(30, 36, 50, 0.06),
|
||||
--box-shadow-strong:
|
||||
0px 5px 10px 0px rgba(30, 36, 50, 0.08), 0px 1px 1px 0px rgba(30, 36, 50, 0.06),
|
||||
0px 3px 5px 0px rgba(30, 36, 50, 0.06);
|
||||
--box-shadow-block: 0px 10px 30px 0px rgba(30, 36, 50, 0.07), 0px 0px 1px 0px rgba(30, 36, 50, 0.1);
|
||||
--box-shadow-block-strong: 0px 15px 50px 0px rgba(30, 36, 50, 0.14), 0px 0px 1px 0px rgba(30, 36, 50, 0.15);
|
||||
color: var(--color-dark-1);
|
||||
font-family: var(--font-global);
|
||||
font-size: 17px;
|
||||
font-weight: 400;
|
||||
line-height: 1.725;
|
||||
@ -201,9 +200,6 @@
|
||||
.theme-slick .inner-nav ul li {
|
||||
margin: 0 18px;
|
||||
}
|
||||
.theme-slick .inner-nav > ul > li > a {
|
||||
opacity: 0.7;
|
||||
}
|
||||
.theme-slick .inner-nav ul li a {
|
||||
position: relative;
|
||||
}
|
||||
@ -233,11 +229,7 @@
|
||||
.theme-slick .mobile-on .desktop-nav ul {
|
||||
background: rgba(30, 36, 50, 0.99);
|
||||
}
|
||||
.theme-slick .mobile-on .desktop-nav ul li a,
|
||||
.theme-slick .inner-nav ul li .mn-sub li a,
|
||||
.theme-slick .mn-group-title {
|
||||
color: rgba(255, 255, 255, 0.9) !important;
|
||||
}
|
||||
|
||||
.theme-slick .form label {
|
||||
margin-bottom: 15px;
|
||||
font-size: 18px;
|
||||
|
@ -238,10 +238,10 @@ Primary use: Multipurpose Template
|
||||
--gradient-primary-alpha-2: linear-gradient(90deg, transparent 13%, var(--color-primary-1) 60%);
|
||||
--border-radius-default: 4px;
|
||||
--border-radius-large: 30px;
|
||||
--box-shadow: 0px 5px 10px 0px rgba(0, 0, 0, 0.05), 0px 1px 1px 0px rgba(0, 0, 0, 0.03),
|
||||
0px 3px 5px 0px rgba(0, 0, 0, 0.03);
|
||||
--box-shadow-strong: 0px 5px 10px 0px rgba(0, 0, 0, 0.08), 0px 1px 1px 0px rgba(0, 0, 0, 0.06),
|
||||
0px 3px 5px 0px rgba(0, 0, 0, 0.06);
|
||||
--box-shadow:
|
||||
0px 5px 10px 0px rgba(0, 0, 0, 0.05), 0px 1px 1px 0px rgba(0, 0, 0, 0.03), 0px 3px 5px 0px rgba(0, 0, 0, 0.03);
|
||||
--box-shadow-strong:
|
||||
0px 5px 10px 0px rgba(0, 0, 0, 0.08), 0px 1px 1px 0px rgba(0, 0, 0, 0.06), 0px 3px 5px 0px rgba(0, 0, 0, 0.06);
|
||||
--box-shadow-block: 0px 3px 50px 0px rgba(0, 0, 0, 0.05);
|
||||
--box-shadow-block-strong: 0px 3px 50px 0px rgba(0, 0, 0, 0.15);
|
||||
--transition-default: all 0.27s cubic-bezier(0, 0, 0.58, 1);
|
||||
@ -746,7 +746,6 @@ video {
|
||||
|
||||
body {
|
||||
color: var(--color-dark-1);
|
||||
font-family: var(--font-global);
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
letter-spacing: normal;
|
||||
@ -3835,7 +3834,6 @@ a.logo:hover {
|
||||
.inner-nav ul {
|
||||
margin: auto;
|
||||
font-size: 17px;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
letter-spacing: 0;
|
||||
line-height: 1.3;
|
||||
@ -3880,7 +3878,6 @@ a.logo:hover {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
height: var(--menu-bar-height);
|
||||
opacity: 0.65;
|
||||
}
|
||||
.main-nav:not(.mobile-on).small-height .inner-nav > ul > li > a {
|
||||
height: var(--menu-bar-height-scrolled) !important;
|
||||
@ -3925,7 +3922,7 @@ a.logo:hover {
|
||||
transition: var(--transition-default);
|
||||
}
|
||||
.mn-sub {
|
||||
display: none;
|
||||
/* opacity: 0; */
|
||||
width: 220px;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
@ -3979,7 +3976,6 @@ a.logo:hover {
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
letter-spacing: 0;
|
||||
color: var(--color-gray-light-5) !important;
|
||||
outline-offset: -2px !important;
|
||||
transition: var(--transition-default);
|
||||
}
|
||||
@ -3990,7 +3986,6 @@ a.logo:hover {
|
||||
.inner-nav ul li .mn-sub li a:hover,
|
||||
.mn-sub li a.active {
|
||||
background: rgba(255, 255, 255, 0.09);
|
||||
color: var(--color-gray-light-1) !important;
|
||||
}
|
||||
.mn-sub:not(.mn-has-multi) li ul {
|
||||
left: 100%;
|
||||
@ -4324,20 +4319,11 @@ a.logo:hover {
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
.main-nav.dark .inner-nav ul > li > a {
|
||||
font-size: 18px;
|
||||
color: #fff;
|
||||
opacity: 0.78;
|
||||
font-weight: 500;
|
||||
line-height: 1.2em;
|
||||
padding: 10px;
|
||||
}
|
||||
.main-nav.dark .inner-nav ul > li > a:hover,
|
||||
.main-nav.dark .inner-nav ul > li > a.active {
|
||||
color: #fff;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.main-nav.dark .inner-nav ul li .mn-sub li a {
|
||||
opacity: 1;
|
||||
}
|
||||
.main-nav.dark .main-nav-icon-cart {
|
||||
opacity: 1;
|
||||
}
|
||||
@ -4361,13 +4347,13 @@ a.logo:hover {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
text-decoration: none;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
/* color: rgba(255, 255, 255, 0.9); */
|
||||
}
|
||||
.main-nav.dark .mn-sub {
|
||||
/* .main-nav.dark .mn-sub {
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
} */
|
||||
.main-nav.dark .mi-chevron-down,
|
||||
.main-nav.dark.body-scrolled .inner-nav ul > li > a:hover .mi-chevron-down,
|
||||
.main-nav.dark.body-scrolled .inner-nav ul > li > a.active .mi-chevron-down {
|
||||
|
@ -2,22 +2,106 @@ import { BeforeFooterBlock } from "@/components/Blocks/BeforeFooter";
|
||||
import { BlogCardItemSkeleton } from "@/components/Blogs/BlogCardItem";
|
||||
import Blogs from "@/components/Blogs/Blogs";
|
||||
import HeroOther from "@/components/HeroOther";
|
||||
import { getDefaultMetadata } from "@/utils/metadata";
|
||||
import { sanitizePageNumber } from "@/utils/sanitize";
|
||||
import { Metadata } from "next";
|
||||
import { headers } from "next/headers";
|
||||
import { Suspense } from "react";
|
||||
|
||||
export const metadata = {
|
||||
title: "Blog - Cochise Oncology",
|
||||
description: "Blog - Cochise Oncology",
|
||||
};
|
||||
const metaDesc =
|
||||
"Explore the latest insights, news, and patient resources on the Cochise Oncology blog. Stay informed about cancer treatments, patient support services, and wellness tips. Read our expert articles today.";
|
||||
|
||||
export async function generateMetadata(): Promise<Metadata> {
|
||||
const metadata = await getDefaultMetadata();
|
||||
metadata.title = `Blog - ${metadata.openGraph?.siteName}`;
|
||||
metadata.description = metaDesc;
|
||||
|
||||
return metadata;
|
||||
}
|
||||
|
||||
export default async function BlogPage({ searchParams }: { searchParams?: Promise<{ page?: string; s?: string }> }) {
|
||||
const params = await searchParams;
|
||||
const paramsPage = params?.page;
|
||||
const paramsSearch = params?.s;
|
||||
const page = sanitizePageNumber(paramsPage);
|
||||
const headersList = await headers();
|
||||
const mainUrl = headersList.get("x-main-url");
|
||||
const fullUrl = headersList.get("x-full-url");
|
||||
const siteName = headersList.get("x-site-name");
|
||||
|
||||
const jsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@graph": [
|
||||
{
|
||||
"@type": "WebPage",
|
||||
"@id": fullUrl,
|
||||
url: fullUrl,
|
||||
name: `Blog - ${siteName}`,
|
||||
isPartOf: {
|
||||
"@id": `${mainUrl}/#website`,
|
||||
},
|
||||
datePublished: "2024-07-18T16:42:14+00:00",
|
||||
dateModified: "2025-02-27T01:20:38+00:00",
|
||||
description: metaDesc,
|
||||
breadcrumb: {
|
||||
"@id": `${fullUrl}#breadcrumb`,
|
||||
},
|
||||
inLanguage: "en-US",
|
||||
potentialAction: [
|
||||
{
|
||||
"@type": "ReadAction",
|
||||
target: [fullUrl],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"@type": "WebSite",
|
||||
"@id": `${mainUrl}/#website`,
|
||||
url: `${mainUrl}/`,
|
||||
name: siteName,
|
||||
description: "",
|
||||
publisher: {
|
||||
"@id": `${mainUrl}/#organization`,
|
||||
},
|
||||
potentialAction: [
|
||||
{
|
||||
"@type": "SearchAction",
|
||||
target: {
|
||||
"@type": "EntryPoint",
|
||||
urlTemplate: `${mainUrl}/?s={search_term_string}`,
|
||||
},
|
||||
"query-input": {
|
||||
"@type": "PropertyValueSpecification",
|
||||
valueRequired: true,
|
||||
valueName: "search_term_string",
|
||||
},
|
||||
},
|
||||
],
|
||||
inLanguage: "en-US",
|
||||
},
|
||||
{
|
||||
"@type": "Organization",
|
||||
"@id": `${mainUrl}/#organization`,
|
||||
name: siteName,
|
||||
url: `${mainUrl}/`,
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
inLanguage: "en-US",
|
||||
"@id": `${mainUrl}/#/schema/logo/image/`,
|
||||
url: `${mainUrl}/assets/images/logo-dark.webp`,
|
||||
contentUrl: `${mainUrl}/assets/images/logo-dark.webp`,
|
||||
caption: siteName,
|
||||
},
|
||||
image: {
|
||||
"@id": `${mainUrl}/#/schema/logo/image/`,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} />
|
||||
<HeroOther title="Blog" />
|
||||
|
||||
<section className="page-section" id="blog">
|
||||
|
@ -2,14 +2,24 @@ import { BeforeFooterBlock } from "@/components/Blocks/BeforeFooter";
|
||||
import { BlogCardItemSkeleton } from "@/components/Blogs/BlogCardItem";
|
||||
import Blogs from "@/components/Blogs/Blogs";
|
||||
import HeroOther from "@/components/HeroOther";
|
||||
import { fetchBlogCategoryBySlug } from "@/services/payload/blog";
|
||||
import { getDefaultMetadata } from "@/utils/metadata";
|
||||
import { sanitizePageNumber } from "@/utils/sanitize";
|
||||
import { Metadata } from "next";
|
||||
// import { headers } from "next/headers";
|
||||
import { headers } from "next/headers";
|
||||
import { notFound } from "next/navigation";
|
||||
import { Suspense } from "react";
|
||||
|
||||
export async function generateMetadata(): Promise<Metadata> {
|
||||
export async function generateMetadata({ params }: { params: Promise<{ path: string[0] }> }): Promise<Metadata> {
|
||||
const path = (await params)?.path;
|
||||
const paramsCategory = path?.[0] ?? "";
|
||||
const metadata = await getDefaultMetadata();
|
||||
|
||||
const category = await fetchBlogCategoryBySlug(paramsCategory);
|
||||
if (!!category?.data) {
|
||||
metadata.title = `${category.data.name} Archives - ${metadata.openGraph?.siteName}`;
|
||||
}
|
||||
|
||||
return metadata;
|
||||
}
|
||||
|
||||
@ -21,19 +31,92 @@ export default async function CategoryPage({
|
||||
searchParams?: Promise<{ page?: string; s?: string }>;
|
||||
}) {
|
||||
const path = (await params)?.path;
|
||||
// const headersList = await headers();
|
||||
// const paramsCategory = path?.[0] ?? "";
|
||||
const paramsCategory = path?.[0] ?? "";
|
||||
const paramsPage = path?.[2] ?? "";
|
||||
const paramsSearch = (await searchParams)?.s;
|
||||
const page = sanitizePageNumber(paramsPage);
|
||||
const headersList = await headers();
|
||||
const mainUrl = headersList.get("x-main-url");
|
||||
const fullUrl = headersList.get("x-full-url");
|
||||
const siteName = headersList.get("x-site-name");
|
||||
|
||||
const category = await fetchBlogCategoryBySlug(paramsCategory);
|
||||
if (!category) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
const jsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@graph": [
|
||||
{
|
||||
"@type": "CollectionPage",
|
||||
"@id": fullUrl,
|
||||
url: fullUrl,
|
||||
name: `${category.data.name} - ${siteName}`,
|
||||
isPartOf: {
|
||||
"@id": `${mainUrl}/#website`,
|
||||
},
|
||||
primaryImageOfPage: {
|
||||
"@id": `${fullUrl}#primaryimage`,
|
||||
},
|
||||
image: {
|
||||
"@id": `${fullUrl}#primaryimage`,
|
||||
},
|
||||
inLanguage: "en-US",
|
||||
},
|
||||
{
|
||||
"@type": "WebSite",
|
||||
"@id": `${mainUrl}/#website`,
|
||||
url: `${mainUrl}/`,
|
||||
name: siteName,
|
||||
description: "",
|
||||
publisher: {
|
||||
"@id": `${mainUrl}/#organization`,
|
||||
},
|
||||
potentialAction: [
|
||||
{
|
||||
"@type": "SearchAction",
|
||||
target: {
|
||||
"@type": "EntryPoint",
|
||||
urlTemplate: `${mainUrl}/?s={search_term_string}`,
|
||||
},
|
||||
"query-input": {
|
||||
"@type": "PropertyValueSpecification",
|
||||
valueRequired: true,
|
||||
valueName: "search_term_string",
|
||||
},
|
||||
},
|
||||
],
|
||||
inLanguage: "en-US",
|
||||
},
|
||||
{
|
||||
"@type": "Organization",
|
||||
"@id": `${mainUrl}/#organization`,
|
||||
name: siteName,
|
||||
url: `${mainUrl}/`,
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
inLanguage: "en-US",
|
||||
"@id": `${mainUrl}/#/schema/logo/image/`,
|
||||
url: `${mainUrl}/assets/images/logo-dark.webp`,
|
||||
contentUrl: `${mainUrl}/assets/images/logo-dark.webp`,
|
||||
caption: siteName,
|
||||
},
|
||||
image: {
|
||||
"@id": `${mainUrl}/#/schema/logo/image/`,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<HeroOther title="Blog" />
|
||||
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} />
|
||||
<HeroOther title={`Category: ${category.data.name}`} />
|
||||
|
||||
<section className="page-section" id="blog">
|
||||
<div className="w-full max-w-7xl mx-auto px-4 md:px-8">
|
||||
<form action={`category/chemotherapy/page/1`} method="GET">
|
||||
<form action={`/category/${paramsCategory}`} method="GET">
|
||||
<div className="input-group">
|
||||
<input
|
||||
type="text"
|
||||
@ -52,7 +135,7 @@ export default async function CategoryPage({
|
||||
</div>
|
||||
|
||||
<Suspense fallback={<Loading />}>
|
||||
<Blogs preset="categories" page={page} search={paramsSearch} />
|
||||
<Blogs preset="categories" categoryId={category.data.id} page={page} search={paramsSearch} />
|
||||
</Suspense>
|
||||
</section>
|
||||
|
||||
|
@ -8,14 +8,27 @@ import { getDefaultMetadata } from "@/utils/metadata";
|
||||
import "@public/assets/css/styles.css";
|
||||
import "jarallax/dist/jarallax.min.css";
|
||||
import { Metadata } from "next";
|
||||
import { Roboto } from "next/font/google";
|
||||
import { Roboto, Noto_Sans } from "next/font/google";
|
||||
import "photoswipe/dist/photoswipe.css";
|
||||
import "react-modal-video/css/modal-video.css";
|
||||
import "swiper/css";
|
||||
import "swiper/css/effect-fade";
|
||||
import "tippy.js/dist/tippy.css";
|
||||
|
||||
const roboto = Roboto({ subsets: ["latin"] });
|
||||
const roboto = Roboto({
|
||||
weight: ["400", "500", "600", "700", "800"],
|
||||
style: ["normal", "italic"],
|
||||
subsets: ["latin"],
|
||||
display: "swap",
|
||||
variable: "--font-roboto",
|
||||
});
|
||||
const notoSans = Noto_Sans({
|
||||
weight: ["400", "500", "600"],
|
||||
style: ["normal", "italic"],
|
||||
subsets: ["latin"],
|
||||
display: "swap",
|
||||
variable: "--font-noto-sans",
|
||||
});
|
||||
|
||||
export async function generateMetadata(): Promise<Metadata> {
|
||||
const metadata = await getDefaultMetadata();
|
||||
@ -28,9 +41,9 @@ export default function MainLayout({
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
return (
|
||||
<html lang="en" className={`no-mobile no-touch ${roboto.className}`}>
|
||||
<html lang="en" className={`no-mobile no-touch ${roboto.variable} ${notoSans.variable}`}>
|
||||
<InitialScript />
|
||||
<body className="appear-animate body">
|
||||
<body className="appear-animate body font-fontMain">
|
||||
<div className="theme-slick">
|
||||
<div className="page" id="top">
|
||||
<Header links={navMenuData} />
|
||||
|
@ -111,7 +111,7 @@ export default async function Home() {
|
||||
{
|
||||
"@type": "Organization",
|
||||
"@id": `${fullUrl}#organization`,
|
||||
name: "Cochise Oncology",
|
||||
name: siteName,
|
||||
url: fullUrl,
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
|
157
src/app/(main)/tag/[...path]/page.tsx
Normal file
157
src/app/(main)/tag/[...path]/page.tsx
Normal file
@ -0,0 +1,157 @@
|
||||
import { BeforeFooterBlock } from "@/components/Blocks/BeforeFooter";
|
||||
import { BlogCardItemSkeleton } from "@/components/Blogs/BlogCardItem";
|
||||
import Blogs from "@/components/Blogs/Blogs";
|
||||
import HeroOther from "@/components/HeroOther";
|
||||
import { fetchBlogTagBySlug } from "@/services/payload/blog";
|
||||
import { getDefaultMetadata } from "@/utils/metadata";
|
||||
import { sanitizePageNumber } from "@/utils/sanitize";
|
||||
import { Metadata } from "next";
|
||||
import { headers } from "next/headers";
|
||||
import { notFound } from "next/navigation";
|
||||
import { Suspense } from "react";
|
||||
|
||||
export async function generateMetadata({ params }: { params: Promise<{ path: string[0] }> }): Promise<Metadata> {
|
||||
const path = (await params)?.path;
|
||||
const paramsTag = path?.[0] ?? "";
|
||||
const metadata = await getDefaultMetadata();
|
||||
|
||||
const tag = await fetchBlogTagBySlug(paramsTag);
|
||||
if (!!tag?.data) {
|
||||
metadata.title = `${tag.data.name} Archives - ${metadata.openGraph?.siteName}`;
|
||||
}
|
||||
|
||||
return metadata;
|
||||
}
|
||||
|
||||
export default async function TagPage({
|
||||
params,
|
||||
searchParams,
|
||||
}: {
|
||||
params?: Promise<{ path: string[] }>;
|
||||
searchParams?: Promise<{ page?: string; s?: string }>;
|
||||
}) {
|
||||
const path = (await params)?.path;
|
||||
const paramsTag = path?.[0] ?? "";
|
||||
const paramsPage = path?.[2] ?? "";
|
||||
const paramsSearch = (await searchParams)?.s;
|
||||
const page = sanitizePageNumber(paramsPage);
|
||||
const headersList = await headers();
|
||||
const mainUrl = headersList.get("x-main-url");
|
||||
const fullUrl = headersList.get("x-full-url");
|
||||
const siteName = headersList.get("x-site-name");
|
||||
|
||||
const tag = await fetchBlogTagBySlug(paramsTag);
|
||||
if (!tag) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
const jsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@graph": [
|
||||
{
|
||||
"@type": "CollectionPage",
|
||||
"@id": fullUrl,
|
||||
url: fullUrl,
|
||||
name: `${tag.data.name} - ${siteName}`,
|
||||
isPartOf: {
|
||||
"@id": `${mainUrl}/#website`,
|
||||
},
|
||||
primaryImageOfPage: {
|
||||
"@id": `${fullUrl}#primaryimage`,
|
||||
},
|
||||
image: {
|
||||
"@id": `${fullUrl}#primaryimage`,
|
||||
},
|
||||
inLanguage: "en-US",
|
||||
},
|
||||
{
|
||||
"@type": "WebSite",
|
||||
"@id": `${mainUrl}/#website`,
|
||||
url: `${mainUrl}/`,
|
||||
name: siteName,
|
||||
description: "",
|
||||
publisher: {
|
||||
"@id": `${mainUrl}/#organization`,
|
||||
},
|
||||
potentialAction: [
|
||||
{
|
||||
"@type": "SearchAction",
|
||||
target: {
|
||||
"@type": "EntryPoint",
|
||||
urlTemplate: `${mainUrl}/?s={search_term_string}`,
|
||||
},
|
||||
"query-input": {
|
||||
"@type": "PropertyValueSpecification",
|
||||
valueRequired: true,
|
||||
valueName: "search_term_string",
|
||||
},
|
||||
},
|
||||
],
|
||||
inLanguage: "en-US",
|
||||
},
|
||||
{
|
||||
"@type": "Organization",
|
||||
"@id": `${mainUrl}/#organization`,
|
||||
name: siteName,
|
||||
url: `${mainUrl}/`,
|
||||
logo: {
|
||||
"@type": "ImageObject",
|
||||
inLanguage: "en-US",
|
||||
"@id": `${mainUrl}/#/schema/logo/image/`,
|
||||
url: `${mainUrl}/assets/images/logo-dark.webp`,
|
||||
contentUrl: `${mainUrl}/assets/images/logo-dark.webp`,
|
||||
caption: siteName,
|
||||
},
|
||||
image: {
|
||||
"@id": `${mainUrl}/#/schema/logo/image/`,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} />
|
||||
<HeroOther title={`Tag: ${tag.data.name}`} />
|
||||
|
||||
<section className="page-section" id="blog">
|
||||
<div className="w-full max-w-7xl mx-auto px-4 md:px-8">
|
||||
<form action={`/tag/${paramsTag}`} method="GET">
|
||||
<div className="input-group">
|
||||
<input
|
||||
type="text"
|
||||
name="s"
|
||||
defaultValue={paramsSearch ?? ""}
|
||||
placeholder="Search blog..."
|
||||
className="input-lg input-circle form-control h-12"
|
||||
/>
|
||||
<div className="input-group-append px-2">
|
||||
<button className="btn btn-info text-white h-12 px-5" type="submit">
|
||||
Search
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<Suspense fallback={<Loading />}>
|
||||
<Blogs preset="tags" tagId={tag.data.id} page={page} search={paramsSearch} />
|
||||
</Suspense>
|
||||
</section>
|
||||
|
||||
<BeforeFooterBlock />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function Loading() {
|
||||
return (
|
||||
<div className="container position-relative">
|
||||
<div className="row">
|
||||
<BlogCardItemSkeleton />
|
||||
<BlogCardItemSkeleton />
|
||||
<BlogCardItemSkeleton />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -33,7 +33,6 @@
|
||||
body {
|
||||
color: var(--foreground);
|
||||
background: var(--background);
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
@layer components {
|
||||
@ -63,6 +62,10 @@ body {
|
||||
.ext-btn-shadow-sm-primary8 {
|
||||
@apply bg-extColorPrimary8 text-white hover:text-white hover:bg-extColorPrimary6 transition-colors;
|
||||
}
|
||||
|
||||
.shadow-nav {
|
||||
@apply !shadow-[0px_0px_10px_0px_rgba(0,0,0,0.24)];
|
||||
}
|
||||
}
|
||||
|
||||
.bg-gradient {
|
||||
|
@ -47,8 +47,8 @@ export function BeforeFooterBlock({ title, description, buttonText, showLinier =
|
||||
)}
|
||||
|
||||
<div className="max-w-4xl mx-auto mt-12">
|
||||
<h2 className="text-4xl font-semibold mb-4">{title ?? placeholderTitle}</h2>
|
||||
<p className="text-lg leading-relaxed mb-6">{description ?? placeholderDescription}</p>
|
||||
<h4 className="text-4xl font-medium mb-3">{title ?? placeholderTitle}</h4>
|
||||
<span className="text-lg leading-relaxed mb-6">{description ?? placeholderDescription}</span>
|
||||
<div className="pt-5">
|
||||
<Link
|
||||
href="/contact"
|
||||
|
@ -7,7 +7,7 @@ export function ContentBlock(props: any) {
|
||||
<div className="container relative">
|
||||
<div className="row">
|
||||
{/* Content */}
|
||||
<div className="col-md-10 offset-md-1 col-lg-8 offset-lg-2">
|
||||
<div className="col-md-10 offset-md-1 col-lg-10 offset-lg-1">
|
||||
{/* Post */}
|
||||
<div className="blog-item mb-10">
|
||||
<div className="blog-item-body">
|
||||
|
@ -100,7 +100,7 @@ export default async function BlogDetail({ slug }: BlogDetailProps) {
|
||||
<div className="container relative">
|
||||
<div className="row">
|
||||
{/* Content */}
|
||||
<div className="col-md-10 offset-md-1 col-lg-8 offset-lg-2">
|
||||
<div className="col-md-10 offset-md-1 col-lg-10 offset-lg-1">
|
||||
{/* Post */}
|
||||
<div className="blog-item mb-80 mb-xs-40">
|
||||
<div className="blog-item-body">
|
||||
@ -133,7 +133,7 @@ export function BlogDetailContentSkeleton() {
|
||||
<div className="container relative">
|
||||
<div className="row">
|
||||
{/* Content */}
|
||||
<div className="col-md-10 offset-md-1 col-lg-8 offset-lg-2">
|
||||
<div className="col-md-10 offset-md-1 col-lg-10 offset-lg-1">
|
||||
{/* Post */}
|
||||
<div className="blog-item mb-80 mb-xs-40">
|
||||
<div className="blog-item-body">
|
||||
|
@ -3,14 +3,37 @@ import { fetchBlog } from "@/services/payload/blog";
|
||||
import { BlogCardItem } from "./BlogCardItem";
|
||||
import { sanitizeBlogContentIntoStringPreview } from "@/utils/sanitize";
|
||||
|
||||
export interface BlogsProps {
|
||||
preset?: "blogs" | "categories";
|
||||
export type BlogsProps = {
|
||||
page: number;
|
||||
search?: string;
|
||||
}
|
||||
} & (
|
||||
| {
|
||||
preset?: "blogs";
|
||||
}
|
||||
| {
|
||||
preset?: "categories";
|
||||
categoryId: number;
|
||||
}
|
||||
| {
|
||||
preset?: "tags";
|
||||
tagId: number;
|
||||
}
|
||||
);
|
||||
|
||||
export default async function Blogs({ page, search, preset = "blogs" }: BlogsProps) {
|
||||
const data = await fetchBlog({ page, search });
|
||||
export default async function Blogs({ page, search, ...params }: BlogsProps) {
|
||||
const fetchBlogParams: Parameters<typeof fetchBlog>[0] = {
|
||||
page,
|
||||
search,
|
||||
};
|
||||
|
||||
if (params.preset === "categories") {
|
||||
fetchBlogParams.categoryId = params.categoryId;
|
||||
}
|
||||
if (params.preset === "tags") {
|
||||
fetchBlogParams.tagId = params.tagId;
|
||||
}
|
||||
|
||||
const data = await fetchBlog(fetchBlogParams);
|
||||
|
||||
if (!data?.totalDocs) return <></>;
|
||||
|
||||
@ -42,7 +65,7 @@ export default async function Blogs({ page, search, preset = "blogs" }: BlogsPro
|
||||
hasNextPage={data.hasNextPage}
|
||||
hasPreviousPage={data.hasPrevPage}
|
||||
totalPages={data.totalPages}
|
||||
usePathParams={preset === "blogs" ? false : true}
|
||||
usePathParams={params.preset === "blogs" ? false : true}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
@ -1,4 +1,6 @@
|
||||
import { fetchContact } from "@/services/payload/contact";
|
||||
import { FaClock, FaFax, FaMapMarkerAlt } from "react-icons/fa";
|
||||
import { GiRotaryPhone } from "react-icons/gi";
|
||||
import { Suspense } from "react";
|
||||
|
||||
export default function Contact() {
|
||||
@ -32,21 +34,7 @@ async function ContactWithData() {
|
||||
{/* Contact Item */}
|
||||
<div className="col-sm-6 mb-xs-30 d-flex align-items-stretch">
|
||||
<div className="alt-features-item border-left mt-0 wow fadeScaleIn" data-wow-delay=".3s">
|
||||
<div className="alt-features-icon">
|
||||
<svg
|
||||
width={24}
|
||||
height={24}
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
>
|
||||
<path d="M12 2C8.134 2 5 5.134 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.866-3.134-7-7-7zm0 9.5c-1.381 0-2.5-1.119-2.5-2.5s1.119-2.5 2.5-2.5 2.5 1.119 2.5 2.5-1.119 2.5-2.5 2.5z" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<FaMapMarkerAlt className="text-4xl m-5" />
|
||||
<h4 className="alt-features-title">Location</h4>
|
||||
<div className="alt-features-descr clearlinks">
|
||||
<div>
|
||||
@ -61,20 +49,7 @@ async function ContactWithData() {
|
||||
{/* Contact Item */}
|
||||
<div className="col-sm-6 d-flex align-items-stretch">
|
||||
<div className="alt-features-item border-left mt-0 wow fadeScaleIn" data-wow-delay=".5s">
|
||||
<div className="alt-features-icon">
|
||||
<svg
|
||||
width={24}
|
||||
height={24}
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
>
|
||||
<path d="M17 2H7C5.9 2 5 2.9 5 4v16c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 17H7V5h10v14zM12 16c.55 0 1-.45 1-1s-.45-1-1-1-1 .45-1 1 .45 1 1 1z" />
|
||||
</svg>
|
||||
</div>
|
||||
<GiRotaryPhone className="text-4xl m-5" />
|
||||
<h4 className="alt-features-title">Phone</h4>
|
||||
<div className="alt-features-descr clearlinks">
|
||||
<div>
|
||||
@ -89,20 +64,7 @@ async function ContactWithData() {
|
||||
{/* Contact Item */}
|
||||
<div className="col-sm-6 mb-xs-30 d-flex align-items-stretch">
|
||||
<div className="alt-features-item border-left mt-0 wow fadeScaleIn" data-wow-delay=".3s">
|
||||
<div className="alt-features-icon">
|
||||
<svg
|
||||
width={24}
|
||||
height={24}
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
>
|
||||
<path d="M12 2C6.486 2 2 6.486 2 12s4.486 10 10 10 10-4.486 10-10S17.514 2 12 2zm0 18c-4.411 0-8-3.589-8-8s3.589-8 8-8 8 3.589 8 8-3.589 8-8 8zm1-8h4v2h-6V7h2v5z" />
|
||||
</svg>
|
||||
</div>
|
||||
<FaClock className="text-4xl m-5" />
|
||||
<h4 className="alt-features-title">Hours</h4>
|
||||
<div className="alt-features-descr clearlinks">
|
||||
{Array.isArray(contact?.hours) &&
|
||||
@ -118,20 +80,7 @@ async function ContactWithData() {
|
||||
{/* Contact Item */}
|
||||
<div className="col-sm-6 mb-xs-30 d-flex align-items-stretch">
|
||||
<div className="alt-features-item border-left mt-0 wow fadeScaleIn" data-wow-delay=".3s">
|
||||
<div className="alt-features-icon">
|
||||
<svg
|
||||
width={24}
|
||||
height={24}
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
>
|
||||
<path d="M12 2C6.486 2 2 6.486 2 12s4.486 10 10 10 10-4.486 10-10S17.514 2 12 2zm0 18c-4.411 0-8-3.589-8-8s3.589-8 8-8 8 3.589 8 8-3.589 8-8 8zm1-12h-2v2h2V8zm0 4h-2v6h2v-6zm-4-2H7v2h2v-2zm6 0h-2v2h2v-2z" />
|
||||
</svg>
|
||||
</div>
|
||||
<FaFax className="text-4xl m-5" />
|
||||
<h4 className="alt-features-title">Fax</h4>
|
||||
<div className="alt-features-descr clearlinks">
|
||||
<div>
|
||||
|
@ -11,8 +11,8 @@ const shareIcons: Record<string, any> = {
|
||||
phone: {
|
||||
link: "tel:+15208036644",
|
||||
dom: (
|
||||
<span className="social-nav flex gap-1 text-2xl lg:text-white">
|
||||
<Image src="/assets/icons/phone.png" alt="Image Description" width={25} height={22} />
|
||||
<span className="social-nav flex text-2xl text-white space-x-3 lg:space-x-1">
|
||||
<Image src="/assets/icons/phone.png" alt="Phone" width={30} height={25} />
|
||||
<b className="text-[17px]">(520) 803-6644</b>
|
||||
</span>
|
||||
),
|
||||
@ -20,7 +20,7 @@ const shareIcons: Record<string, any> = {
|
||||
facebook: {
|
||||
link: "https://www.facebook.com/p/Cochise-Oncology-61556262839823",
|
||||
dom: (
|
||||
<span className="social-nav flex gap-3 text-2xl lg:text-white">
|
||||
<span className="social-nav flex text-2xl text-white space-x-3 lg:space-x-1">
|
||||
<FaFacebook size={25} />
|
||||
<b className="text-[17px] lg:hidden">Facebook</b>
|
||||
</span>
|
||||
@ -29,7 +29,7 @@ const shareIcons: Record<string, any> = {
|
||||
linkedin: {
|
||||
link: "https://linkedin.com/company/cochise-oncology",
|
||||
dom: (
|
||||
<span className="social-nav flex gap-3 text-2xl lg:text-white">
|
||||
<span className="social-nav flex text-2xl text-white space-x-3 lg:space-x-1">
|
||||
<FaLinkedin size={25} />
|
||||
<b className="text-[17px] lg:hidden">Linkedin</b>
|
||||
</span>
|
||||
@ -41,23 +41,13 @@ export default function Header({ links }: { links: typeof navMenuData }) {
|
||||
return (
|
||||
<nav className="main-nav dark stick-fixed wow-menubar wch-unset relative">
|
||||
<div className="main-nav-sub full-wrapper">
|
||||
{/* Logo (* Add your text or image to the link tag. Use SVG or PNG image format.
|
||||
If you use a PNG logo image, the image resolution must be equal 200% of the visible logo
|
||||
image size for support of retina screens. See details in the template documentation. *) */}
|
||||
<div className="nav-logo-wrap local-scroll">
|
||||
<div className="nav-logo-wrap local-scroll lg:hidden">
|
||||
<Link href={`/`} className="logo">
|
||||
<Image
|
||||
src="/assets/images/demo-slick/logo-dark.webp"
|
||||
alt="Your Company Logo"
|
||||
width={105}
|
||||
height={34}
|
||||
className="light-mode-logo"
|
||||
/>
|
||||
<Image
|
||||
src="/assets/images/demo-slick/logo-dark.webp"
|
||||
alt="Your Company Logo"
|
||||
width={405}
|
||||
height={34}
|
||||
alt="Company Logo"
|
||||
width={250}
|
||||
height={150}
|
||||
className="dark-mode-logo"
|
||||
/>
|
||||
</Link>
|
||||
@ -70,30 +60,41 @@ export default function Header({ links }: { links: typeof navMenuData }) {
|
||||
{/* Main Menu */}
|
||||
<div className="inner-nav desktop-nav">
|
||||
<ul className="clearlist local-scroll">
|
||||
{/* Item With Sub */}
|
||||
<li className="!hidden lg:!block">
|
||||
<Link href={`/`} className="logo">
|
||||
<Image
|
||||
src="/assets/images/demo-slick/logo-dark.webp"
|
||||
alt="Company Logo"
|
||||
width={165}
|
||||
height={100}
|
||||
className="dark-mode-logo"
|
||||
/>
|
||||
</Link>
|
||||
</li>
|
||||
<HeaderNav links={links} />
|
||||
{/* End Item With Sub */}
|
||||
</ul>
|
||||
<ul className="items-end clearlist flex flex-col justify-center h-full">
|
||||
<li>
|
||||
<div className="flex flex-col items-center h-full w-full content-center justify-center gap-2">
|
||||
<div className="flex justify-center">
|
||||
<a
|
||||
href="/contact"
|
||||
className="bg-extColorPrimary6 hover:bg-extColorPrimary8 px-3 py-2 rounded-full text-white font-semibold hover:cursor-pointer hover:scale-[1.15] mt-3 lg:mt-0 transition-all duration-300"
|
||||
className="bg-extColorPrimary6 hover:bg-extColorPrimary8 px-4 py-2 rounded-full text-white font-semibold hover:cursor-pointer hover:scale-[1.15] mt-3 lg:mt-0 transition-all duration-300"
|
||||
>
|
||||
REQUEST CONSULTATION
|
||||
</a>
|
||||
</div>
|
||||
<div className="flex justify-between w-full flex-col lg:flex-row">
|
||||
{Object.keys(shareIcons).map((k, idx) => {
|
||||
return (
|
||||
<li key={idx} className="!p-0 !m-0">
|
||||
<div key={idx} className="!p-0 !m-0">
|
||||
<a className="cursor-pointer text-white" href={shareIcons[k].link} target="_blank">
|
||||
{shareIcons[k].dom}
|
||||
</a>
|
||||
</li>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
@ -7,9 +7,13 @@ import { scrollToElement } from "@/utils/scrollToElement";
|
||||
import { toggleMobileMenu } from "@/utils/toggleMobileMenu";
|
||||
import Link from "next/link";
|
||||
import { Fragment, useEffect, useRef, useState } from "react";
|
||||
import { FaCaretDown, FaCaretRight } from "react-icons/fa";
|
||||
|
||||
export default function HeaderNav({ links, animateY = false }: { links: typeof navMenuData; animateY?: boolean }) {
|
||||
const [hoveredNavItem, setHoveredNavItem] = useState("");
|
||||
const [hoveredSubNavItem, setHoveredSubNavItem] = useState("");
|
||||
const [isDropdownOpen, setIsDropdownOpen] = useState([""]);
|
||||
const [isSubDropdownOpen, setIsSubDropdownOpen] = useState("");
|
||||
const dropdownRef = useRef(null);
|
||||
|
||||
const toggleDropdown = (section: string[]) => {
|
||||
@ -40,7 +44,10 @@ export default function HeaderNav({ links, animateY = false }: { links: typeof n
|
||||
<Fragment key={index}>
|
||||
<li>
|
||||
{!Array.isArray(link?.child) && (
|
||||
<Link href={link.href}>
|
||||
<Link
|
||||
href={link.href}
|
||||
className="!text-white hover:!text-extColorPrimary3 !text-[20px] !transition-all !duration-500"
|
||||
>
|
||||
{animateY ? (
|
||||
<span className="btn-animate-y">
|
||||
<span className="btn-animate-y-1">{link.text}</span>
|
||||
@ -55,35 +62,54 @@ export default function HeaderNav({ links, animateY = false }: { links: typeof n
|
||||
)}
|
||||
|
||||
{Array.isArray(link?.child) && (
|
||||
<>
|
||||
<Link href={link?.href ?? "#"} className="mn-has-sub flex justify-between">
|
||||
{link.text} <i className="mi-chevron-down" onClick={() => toggleDropdown([link.text])} />
|
||||
<div onMouseOver={() => setHoveredNavItem(`${index}`)} onMouseLeave={() => setHoveredNavItem("")}>
|
||||
<Link
|
||||
href={link?.href ?? "#"}
|
||||
className="mn-has-sub !flex justify-between items-center !text-white hover:!text-extColorPrimary3 !text-[20px] !transition-all !duration-500"
|
||||
onClick={() => toggleDropdown([link.text])}
|
||||
>
|
||||
{link.text} <FaCaretDown className="ml-2" />
|
||||
</Link>
|
||||
|
||||
<ul
|
||||
className={`mn-sub to-right ${isDropdownOpen.includes(link.text) && "open"} !bg-extColorPrimary8`}
|
||||
className={`font-fontSecondary mn-sub to-right mt-2 ${isDropdownOpen.includes(link.text) && "open"} !bg-extColorPrimary8 ${hoveredNavItem.includes(`${index}`) ? "lg:visible lg:opacity-100 lg:z-10" : "lg:invisible lg:opacity-0"} !transition-all !duration-300 lg:shadow-nav`}
|
||||
ref={dropdownRef}
|
||||
>
|
||||
{link.child.map((subLink: any, subLinkIdx: number) => (
|
||||
<li key={subLinkIdx}>
|
||||
<li
|
||||
key={subLinkIdx}
|
||||
onMouseOver={() => setHoveredSubNavItem(`${index}-${subLinkIdx}`)}
|
||||
onMouseLeave={() => setHoveredSubNavItem("")}
|
||||
>
|
||||
{!Array.isArray(subLink?.child) && (
|
||||
<Link href={subLink?.href} onClick={() => toggleMobileMenu()}>
|
||||
<Link
|
||||
href={subLink?.href}
|
||||
onClick={() => toggleMobileMenu()}
|
||||
className="!text-[14px] !text-white hover:!bg-extColorPrimary5 hover:!text-extColorPrimary3 !transition-all !duration-500"
|
||||
>
|
||||
{subLink?.text}
|
||||
</Link>
|
||||
)}
|
||||
{Array.isArray(subLink?.child) && (
|
||||
<>
|
||||
<Link href={subLink?.href ?? "#"} className="mn-has-sub !flex !justify-between">
|
||||
<span>{subLink.text}</span>
|
||||
<i className="mi-chevron-down" onClick={() => toggleDropdown([link.text, subLink.text])} />
|
||||
<Link
|
||||
href={subLink?.href ?? "#"}
|
||||
className="mn-has-sub !flex !justify-between !items-center !text-white hover:!bg-extColorPrimary5 hover:!text-extColorPrimary3 transition-all duration-500"
|
||||
onClick={() => setIsSubDropdownOpen(`${index}-${subLinkIdx}`)}
|
||||
>
|
||||
<span className="!text-[14px]">{subLink.text}</span>
|
||||
<FaCaretRight className="ml-2" />
|
||||
</Link>
|
||||
|
||||
<ul
|
||||
className={`mn-sub to-right ${isDropdownOpen.includes(subLink.text) && "open"} !bg-extColorPrimary8`}
|
||||
className={`mn-sub to-right ${isSubDropdownOpen.includes(`${index}-${subLinkIdx}`) && "open"} ${hoveredSubNavItem.includes(`${index}-${subLinkIdx}`) ? "lg:visible lg:opacity-100 lg:z-10" : "lg:invisible lg:opacity-0"} !bg-extColorPrimary8 !transition-all !duration-300 lg:shadow-nav`}
|
||||
>
|
||||
{subLink.child.map((subLink2: any, subLinkIdx2: number) => (
|
||||
<li key={subLinkIdx2}>
|
||||
<Link href={subLink2?.href} onClick={() => toggleMobileMenu()}>
|
||||
<Link
|
||||
href={subLink2?.href}
|
||||
className="!text-[14px] !items-center !text-white hover:!bg-extColorPrimary5 hover:!text-extColorPrimary3 transition-all duration-500"
|
||||
onClick={() => toggleMobileMenu()}
|
||||
>
|
||||
{subLink2?.text}
|
||||
</Link>
|
||||
</li>
|
||||
@ -94,12 +120,12 @@ export default function HeaderNav({ links, animateY = false }: { links: typeof n
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</>
|
||||
</div>
|
||||
)}
|
||||
</li>
|
||||
{index != links.length - 1 && (
|
||||
<div
|
||||
className="text-white bg-white h-[1px] md:h-[25px] mx-2 opacity-[0.3]"
|
||||
className="text-white bg-white h-[1px] lg:h-[25px] mx-2 opacity-[0.3]"
|
||||
style={{ border: "1px solid white" }}
|
||||
/>
|
||||
)}
|
||||
|
@ -16,14 +16,14 @@ const shareIcons: Record<string, any> = {
|
||||
|
||||
export default function HeroOther({ title, img, createdAt, shareUrl }: HeroOtherProps) {
|
||||
return (
|
||||
<section className="page-section bg-dark-1 bg-gradient-gray-dark-1 light-content bg-scroll overflow-hidden !py-20 md:!pt-52 md:!pb-28 relative min-h-[48vh]">
|
||||
<section className="page-section bg-dark-1 bg-gradient-gray-dark-1 light-content bg-scroll overflow-hidden !py-20 !pt-52 md:!pb-28 relative min-h-[48vh]">
|
||||
{/* <!-- Background Shape --> */}
|
||||
<div className="bg-shape-1 w-full h-full opacity-50 bg-contain">
|
||||
<Image src={img || "/assets/images/hero-default.webp"} alt="" fill className="object-cover" />
|
||||
</div>
|
||||
{/* <!-- End Background Shape --> */}
|
||||
|
||||
<div className="container position-relative pt-sm-40 text-center">
|
||||
<div className="container position-relative text-center">
|
||||
<div className="row">
|
||||
<div className="col-md-10 offset-md-1 col-lg-8 offset-lg-2">
|
||||
<h1 className="text-5xl !font-medium mb-10 leading-[1.5]">{title ?? ""}</h1>
|
||||
|
@ -5,6 +5,7 @@ import { init_wow } from "@/utils/initWow";
|
||||
import { parallaxMouseMovement, parallaxScroll } from "@/utils/parallax";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { useEffect } from "react";
|
||||
import { GoogleTagManager } from "@next/third-parties/google";
|
||||
|
||||
export default function InitialScript() {
|
||||
const path = usePathname();
|
||||
@ -36,5 +37,9 @@ export default function InitialScript() {
|
||||
}
|
||||
}, []);
|
||||
|
||||
return <></>;
|
||||
return (
|
||||
<>
|
||||
<GoogleTagManager gtmId="GTM-XYZ" />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -28,8 +28,13 @@ export default function Pagination({
|
||||
const searchParams = new URLSearchParams(url.search);
|
||||
|
||||
if (usePathParams) {
|
||||
searchParams.set("page", `${page}`);
|
||||
window.location.href = `${pathName}/page/${page}/?${searchParams}`;
|
||||
let updatedPath = "";
|
||||
if (pathName.includes("/page")) {
|
||||
updatedPath = pathName.replace(/\/page\/\d+/, `/page/${page}`);
|
||||
} else {
|
||||
updatedPath = `${pathName}/page/${page}`;
|
||||
}
|
||||
window.location.href = `${updatedPath}?${searchParams}`;
|
||||
} else {
|
||||
searchParams.set("page", `${page}`);
|
||||
window.location.href = `${pathName}/?${searchParams}`;
|
||||
|
@ -6,10 +6,65 @@
|
||||
* and re-run `payload generate:types` to regenerate this file.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Supported timezones in IANA format.
|
||||
*
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "supportedTimezones".
|
||||
*/
|
||||
export type SupportedTimezones =
|
||||
| 'Pacific/Midway'
|
||||
| 'Pacific/Niue'
|
||||
| 'Pacific/Honolulu'
|
||||
| 'Pacific/Rarotonga'
|
||||
| 'America/Anchorage'
|
||||
| 'Pacific/Gambier'
|
||||
| 'America/Los_Angeles'
|
||||
| 'America/Tijuana'
|
||||
| 'America/Denver'
|
||||
| 'America/Phoenix'
|
||||
| 'America/Chicago'
|
||||
| 'America/Guatemala'
|
||||
| 'America/New_York'
|
||||
| 'America/Bogota'
|
||||
| 'America/Caracas'
|
||||
| 'America/Santiago'
|
||||
| 'America/Buenos_Aires'
|
||||
| 'America/Sao_Paulo'
|
||||
| 'Atlantic/South_Georgia'
|
||||
| 'Atlantic/Azores'
|
||||
| 'Atlantic/Cape_Verde'
|
||||
| 'Europe/London'
|
||||
| 'Europe/Berlin'
|
||||
| 'Africa/Lagos'
|
||||
| 'Europe/Athens'
|
||||
| 'Africa/Cairo'
|
||||
| 'Europe/Moscow'
|
||||
| 'Asia/Riyadh'
|
||||
| 'Asia/Dubai'
|
||||
| 'Asia/Baku'
|
||||
| 'Asia/Karachi'
|
||||
| 'Asia/Tashkent'
|
||||
| 'Asia/Calcutta'
|
||||
| 'Asia/Dhaka'
|
||||
| 'Asia/Almaty'
|
||||
| 'Asia/Jakarta'
|
||||
| 'Asia/Bangkok'
|
||||
| 'Asia/Shanghai'
|
||||
| 'Asia/Singapore'
|
||||
| 'Asia/Tokyo'
|
||||
| 'Asia/Seoul'
|
||||
| 'Australia/Sydney'
|
||||
| 'Pacific/Guam'
|
||||
| 'Pacific/Noumea'
|
||||
| 'Pacific/Auckland'
|
||||
| 'Pacific/Fiji';
|
||||
|
||||
export interface Config {
|
||||
auth: {
|
||||
users: UserAuthOperations;
|
||||
};
|
||||
blocks: {};
|
||||
collections: {
|
||||
users: User;
|
||||
media: Media;
|
||||
|
@ -5,10 +5,11 @@ import { getPayload, Where } from "payload";
|
||||
type FetchBlogParams = {
|
||||
page?: number;
|
||||
search?: string;
|
||||
categorySlug?: string;
|
||||
categoryId?: number;
|
||||
tagId?: number;
|
||||
};
|
||||
|
||||
export async function fetchBlog({ page, search = "", categorySlug = "" }: FetchBlogParams = {}) {
|
||||
export async function fetchBlog({ page, search = "", categoryId, tagId }: FetchBlogParams = {}) {
|
||||
const payload = await getPayload({ config: payloadConfig });
|
||||
|
||||
const queryCondition: Where = {};
|
||||
@ -17,9 +18,14 @@ export async function fetchBlog({ page, search = "", categorySlug = "" }: FetchB
|
||||
contains: search,
|
||||
};
|
||||
}
|
||||
if (!!categorySlug) {
|
||||
if (!!categoryId) {
|
||||
queryCondition["categories"] = {
|
||||
equals: 9,
|
||||
equals: categoryId,
|
||||
};
|
||||
}
|
||||
if (!!tagId) {
|
||||
queryCondition["tags"] = {
|
||||
equals: tagId,
|
||||
};
|
||||
}
|
||||
|
||||
@ -70,3 +76,35 @@ export async function fetchBlogDetail(slug: string | undefined) {
|
||||
imgUrl,
|
||||
};
|
||||
}
|
||||
|
||||
export async function fetchBlogCategoryBySlug(slug: string) {
|
||||
const payload = await getPayload({ config: payloadConfig });
|
||||
const category = await payload.find({
|
||||
collection: "blogCategories",
|
||||
where: {
|
||||
slug: { equals: slug },
|
||||
},
|
||||
});
|
||||
|
||||
if (!category?.docs?.[0]) return null;
|
||||
|
||||
return {
|
||||
data: category.docs[0],
|
||||
};
|
||||
}
|
||||
|
||||
export async function fetchBlogTagBySlug(slug: string) {
|
||||
const payload = await getPayload({ config: payloadConfig });
|
||||
const tag = await payload.find({
|
||||
collection: "blogTags",
|
||||
where: {
|
||||
slug: { equals: slug },
|
||||
},
|
||||
});
|
||||
|
||||
if (!tag?.docs?.[0]) return null;
|
||||
|
||||
return {
|
||||
data: tag.docs[0],
|
||||
};
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ export async function getDefaultMetadata(): Promise<Metadata> {
|
||||
},
|
||||
openGraph: {
|
||||
siteName,
|
||||
title: siteName,
|
||||
description: metaDesc,
|
||||
type: "website",
|
||||
locale: "en_US",
|
||||
|
@ -4,7 +4,7 @@ export const toggleMobileMenu = () => {
|
||||
const desktop_nav = document.querySelector(".desktop-nav");
|
||||
|
||||
if (desktop_nav.classList.contains("js-opened")) {
|
||||
desktop_nav.style.maxHeight = "0px";
|
||||
desktop_nav.style.maxHeight = "";
|
||||
desktop_nav.classList.remove("js-opened");
|
||||
mobile_nav.classList.remove("active");
|
||||
} else {
|
||||
@ -18,7 +18,7 @@ export const closeMobileMenu = () => {
|
||||
const desktop_nav = document.querySelector(".desktop-nav");
|
||||
|
||||
if (desktop_nav.classList.contains("js-opened")) {
|
||||
desktop_nav.style.maxHeight = "0px";
|
||||
desktop_nav.style.maxHeight = "";
|
||||
desktop_nav.classList.remove("js-opened");
|
||||
mobile_nav.classList.remove("active");
|
||||
}
|
||||
|
@ -8,6 +8,10 @@ export default {
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
fontMain: ["var(--font-noto-sans)"],
|
||||
fontSecondary: ["var(--font-roboto)"],
|
||||
},
|
||||
colors: {
|
||||
background: "var(--background)",
|
||||
foreground: "var(--foreground)",
|
||||
|
Loading…
x
Reference in New Issue
Block a user