diff --git a/app/api/sitemap/route.js b/app/api/sitemap/route.js new file mode 100644 index 0000000..0785098 --- /dev/null +++ b/app/api/sitemap/route.js @@ -0,0 +1,26 @@ +// app/api/sitemap/route.js +import { getAllSlugs } from '@/utils/data'; +import fs from 'fs'; +import path from 'path'; + +export async function POST(req) { + const secret = req.headers.get('x-revalidate-secret'); + if (secret !== process.env.REVALIDATE_TOKEN) { + return new Response('Unauthorized', { status: 401 }); + } + const slugs = await getAllSlugs(); + const siteUrl = process.env.SITE_URL || 'https://yourdomain.com'; + const urls = slugs.map(slugArr => '/' + slugArr.join('/')); + const sitemap = ` + +${urls.map(url => ` + + ${siteUrl}${url} + weekly + 0.7 + +`).join('')} +`; + fs.writeFileSync(path.join(process.cwd(), 'public/sitemap.xml'), sitemap, 'utf8'); + return new Response('Sitemap regenerated', { status: 200 }); +} \ No newline at end of file diff --git a/components/headers/Nav.jsx b/components/headers/Nav.jsx new file mode 100644 index 0000000..62f747d --- /dev/null +++ b/components/headers/Nav.jsx @@ -0,0 +1,122 @@ +"use client"; +import Link from "next/link"; +import React, { useEffect, useState } from "react"; +import { usePathname } from "next/navigation"; +// !text-[var(--current-color)] +export default function Nav({ color = "#fab758" }) { + const [menu, setMenu] = useState([]); + const pathname = usePathname(); + + useEffect(() => { + // Dynamically import Bootstrap + import("bootstrap").then((Bootstrap) => { + const CLASS_NAME = "has-child-dropdown-show"; + + // Save the original toggle function + const originalToggle = Bootstrap.Dropdown.prototype.toggle; + + // Override the toggle function + Bootstrap.Dropdown.prototype.toggle = function () { + // Remove the CLASS_NAME from all dropdowns + document.querySelectorAll("." + CLASS_NAME).forEach(function (e) { + e.classList.remove(CLASS_NAME); + }); + + // Traverse up through the closest dropdown parents + let dd = this._element + .closest(".dropdown") + .parentNode.closest(".dropdown"); + for (; dd && dd !== document; dd = dd.parentNode.closest(".dropdown")) { + dd.classList.add(CLASS_NAME); + } + + // Call the original toggle function + return originalToggle.call(this); + }; + + // Add event listeners for hide.bs.dropdown to remove the CLASS_NAME + document.querySelectorAll(".dropdown").forEach(function (dd) { + dd.addEventListener("hide.bs.dropdown", function (e) { + if (this.classList.contains(CLASS_NAME)) { + this.classList.remove(CLASS_NAME); + e.preventDefault(); + } + e.stopPropagation(); + }); + }); + }); + + // 获取菜单数据 + fetch("/api/get-menu") + .then((res) => res.json()) + .then((data) => setMenu(data.menu || [])); + + // Optional cleanup function for any potential side effects + return () => { + // Cleanup code here (if needed) + }; + }, []); + + // 只在顶级菜单过滤 position + const filterHeaderMenu = (items) => { + return items.filter(item => item.position === 'Header'); + }; + + // 递归渲染菜单 + const renderMenu = (items, level = 0) => { + // 顶级菜单过滤 position + if (level === 0) items = filterHeaderMenu(items); + return items.map((item) => { + const hasChildren = item.children && item.children.length > 0; + const hasHref = !!item.href && item.href !== "#"; + if (hasChildren) { + return ( +
  • 0 ? " dropdown-submenu dropend" : ""}`}> +
    + {/* 如果有href,左侧为可点击跳转,始终用当前item的href */} + {hasHref && ( + 0 ? "dropdown-item" : "nav-link"} !text-[.7rem] !tracking-[normal] hover:!text-[var(--current-color)] after:!text-[var(--current-color)] ${pathname === item.href ? "!text-[var(--current-color)]" : ""}`} + href={item.href} + style={{ paddingRight: 0 }} + > + {item.label} + + )} + {/* 右侧小三角,负责展开下拉 */} + 0 ? "dropdown-item" : "nav-link") + " dropdown-toggle"} !text-[.7rem] !tracking-[normal] hover:!text-[var(--current-color)] after:!text-[var(--current-color)] ${!hasHref && pathname === item.href ? "!text-[var(--current-color)]" : ""}`} + href="#" + data-bs-toggle="dropdown" + aria-expanded="false" + style={hasHref ? { paddingLeft: 8, minWidth: 24 } : {}} + > + {hasHref ? 展开 : item.label} + +
    + +
  • + ); + } else { + return ( +
  • + 0 ? "dropdown-item" : "nav-link"} !text-[.7rem] !tracking-[normal] hover:!text-[var(--current-color)] after:!text-[var(--current-color)] ${pathname === item.href ? "!text-[var(--current-color)]" : ""}`} + href={item.href || "#"} + > + {item.label} + +
  • + ); + } + }); + }; + + return ( + + ); +} diff --git a/components/headers/Nav/NavUI.jsx b/components/headers/Nav/NavUI.jsx deleted file mode 100644 index 703fe51..0000000 --- a/components/headers/Nav/NavUI.jsx +++ /dev/null @@ -1,62 +0,0 @@ -import Link from "next/link"; -import React from "react"; - -export default function NavUI({ menu = [], color = "#fab758" }) { - const filterHeaderMenu = (items) => { - return items.filter(item => item.position === 'Header'); - }; - - const renderMenu = (items, level = 0) => { - if (level === 0) items = filterHeaderMenu(items); - return items.map((item) => { - const hasChildren = item.children && item.children.length > 0; - const hasHref = !!item.href && item.href !== "#"; - if (hasChildren) { - return ( -
  • 0 ? " dropdown-submenu dropend" : ""}`}> -
    - {hasHref && ( - 0 ? "dropdown-item" : "nav-link"} !text-[.7rem] !tracking-[normal] hover:!text-[var(--current-color)] after:!text-[var(--current-color)]`} - href={item.href} - style={{ paddingRight: 0 }} - > - {item.label} - - )} - 0 ? "dropdown-item" : "nav-link") + " dropdown-toggle"} !text-[.7rem] !tracking-[normal] hover:!text-[var(--current-color)] after:!text-[var(--current-color)]`} - href="#" - data-bs-toggle="dropdown" - aria-expanded="false" - style={hasHref ? { paddingLeft: 8, minWidth: 24 } : {}} - > - {hasHref ? 展开 : item.label} - -
    - -
  • - ); - } else { - return ( -
  • - 0 ? "dropdown-item" : "nav-link"} !text-[.7rem] !tracking-[normal] hover:!text-[var(--current-color)] after:!text-[var(--current-color)]`} - href={item.href || "#"} - > - {item.label} - -
  • - ); - } - }); - }; - - return ( - - ); -} \ No newline at end of file diff --git a/components/headers/Nav/index.jsx b/components/headers/Nav/index.jsx deleted file mode 100644 index 2fcad4e..0000000 --- a/components/headers/Nav/index.jsx +++ /dev/null @@ -1,7 +0,0 @@ -import { getMenuData } from '@/utils/data'; -import NavUI from './NavUI'; - -export default async function Nav(props) { - const { menu } = await getMenuData(); - return ; -} \ No newline at end of file diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..0201b1b --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Disallow: + +Sitemap: /sitemap.xml \ No newline at end of file diff --git a/public/sitemap.xml b/public/sitemap.xml new file mode 100644 index 0000000..dbf7ce3 --- /dev/null +++ b/public/sitemap.xml @@ -0,0 +1,328 @@ + + + + + http://192.168.2.200:3001/products/algae-extract/organic-water-soluble-and-non-toxic-food-pigment-extracted-and-processed-from-spirulina-platensis-spirulina-blue-spirulina-extract + weekly + 0.7 + + + + http://192.168.2.200:3001/products/ratio-extract/organic-bladderwrack-extract + weekly + 0.7 + + + + http://192.168.2.200:3001/products/fruit-powders + weekly + 0.7 + + + + http://192.168.2.200:3001/products/ratio-extract/organic-white-kidney-bean-extract + weekly + 0.7 + + + + http://192.168.2.200:3001/products/mushroom-extracts/organic-organic-cordyceps-militaris-extract + weekly + 0.7 + + + + http://192.168.2.200:3001/products/fruit-powders/organic-best-price-organic-freeze-dried-organic-pure-goji-berry-powder + weekly + 0.7 + + + + http://192.168.2.200:3001/products/fruit-powders/organic-extract-natural-pigment-fruit-powder-organic-raspberry-powder-green-pure-powder-extract-powder-food-grade-organic + weekly + 0.7 + + + + http://192.168.2.200:3001/products/fruit-powders/test007 + weekly + 0.7 + + + + http://192.168.2.200:3001/products/vegetable-powders/organic-organic-super-green-powder-supply-food-gradevegetable-powder-wheatgrass-powder + weekly + 0.7 + + + + http://192.168.2.200:3001/news + weekly + 0.7 + + + + http://192.168.2.200:3001/products/vegetable-powders/organic-vegetable-powder-spinach-extract-powder-organic-pure-quality + weekly + 0.7 + + + + http://192.168.2.200:3001/products/ratio-extract/organic-burdock-extract + weekly + 0.7 + + + + http://192.168.2.200:3001/products/algae-extract/test005 + weekly + 0.7 + + + + http://192.168.2.200:3001/products/fruit-powders/organic-supply-food-grade-powder-best-price-organic-raspberry-powder-quality-food-grade-powder-100-pure-fruit-powder + weekly + 0.7 + + + + http://192.168.2.200:3001/products/algae-extract + weekly + 0.7 + + + + http://192.168.2.200:3001/products + weekly + 0.7 + + + + http://192.168.2.200:3001/products/mushroom-extracts/organic-organic-turkey-tail-extract + weekly + 0.7 + + + + http://192.168.2.200:3001/products/mushroom-extracts/organic-organic-tremella-extract + weekly + 0.7 + + + + http://192.168.2.200:3001/products/vegetable-powders/organic-good-quality-plant-extract-natural-pigment-vegetablepowder-freeze-dried-organic-pure-water-kale-powder + weekly + 0.7 + + + + http://192.168.2.200:3001/products/ratio-extract/organic-schisandra-extract + weekly + 0.7 + + + + http://192.168.2.200:3001/products/vegetable-powders/organic-vegetable-seasoning-powder-freeze-dried-organic-pure-quality-barley-grass-powde + weekly + 0.7 + + + + http://192.168.2.200:3001/products/mushroom-extracts/organic-organic-maitake-mushroom-extract + weekly + 0.7 + + + + http://192.168.2.200:3001/products/fruit-powders/organic-100-pure-fruit-powder-instant-filled-powder-mango-powder-freeze-dried-extract-powder + weekly + 0.7 + + + + http://192.168.2.200:3001/products/algae-extract/sub-category + weekly + 0.7 + + + + http://192.168.2.200:3001/products/ratio-extract + weekly + 0.7 + + + + http://192.168.2.200:3001/products/vegetable-powders/organic-plant-extract-good-quality-beetroot-red-colour-powder-beetroot-juice-powder-beetroot-powder + weekly + 0.7 + + + + http://192.168.2.200:3001/products/mushroom-extracts/organic-enoki-mushroom-powder + weekly + 0.7 + + + + http://192.168.2.200:3001/products/fruit-powders/organic-freeze-dried-organic-pure-good-quality-organic-strawberry-powder-extract-natural-pigment-fruit-powder + weekly + 0.7 + + + + http://192.168.2.200:3001/products/algae-extract/Test003 + weekly + 0.7 + + + + http://192.168.2.200:3001/project001 + weekly + 0.7 + + + + http://192.168.2.200:3001/products/fruit-powders/organic-healthy-without-pesticide-residues-fruit-fiber-organic-super-freeze-dried-organic-pure-water-fruit-powder-organic-orange-powder + weekly + 0.7 + + + + http://192.168.2.200:3001/products/mushroom-extracts/organic-organic-chaga-mushroom-extract + weekly + 0.7 + + + + http://192.168.2.200:3001/products/algae-extract/test001 + weekly + 0.7 + + + + http://192.168.2.200:3001/products/mushroom-extracts/organic-oyster-mushroom-powder + weekly + 0.7 + + + + http://192.168.2.200:3001/products/vegetable-powders + weekly + 0.7 + + + + http://192.168.2.200:3001/products/algae-extract/organic-cbd-full-spectrum-pure-thc-free-high-quality-no-pesticide-residue-no-heavy-metal-residue-cbd-distillated-oil-refined-oil + weekly + 0.7 + + + + http://192.168.2.200:3001/products/mushroom-extracts/organic-chaga-mushroom-powder + weekly + 0.7 + + + + http://192.168.2.200:3001/products/fruit-powders/test006 + weekly + 0.7 + + + + http://192.168.2.200:3001/products/mushroom-extracts/organic-organic-lions-mane-mushroom-extract + weekly + 0.7 + + + + http://192.168.2.200:3001/news/test-news + weekly + 0.7 + + + + http://192.168.2.200:3001/products/ratio-extract/organic-ashwagandha-extract + weekly + 0.7 + + + + http://192.168.2.200:3001/products/fruit-powders/organic-organic-pure-quality-best-price-organic-supply-fruit-grade-powder-cranberry-powder + weekly + 0.7 + + + + http://192.168.2.200:3001/products/mushroom-extracts + weekly + 0.7 + + + + http://192.168.2.200:3001/products/ratio-extract/organic-tribulus-terrestris-extract + weekly + 0.7 + + + + http://192.168.2.200:3001/products/algae-extract/test004 + weekly + 0.7 + + + + http://192.168.2.200:3001/products/algae-extract/test002 + weekly + 0.7 + + + + http://192.168.2.200:3001/about + weekly + 0.7 + + + + http://192.168.2.200:3001/contact + weekly + 0.7 + + + + http://192.168.2.200:3001/products/vegetable-powders/organic-best-price-organic-supply-vegetable-grade-powder-100pure-green-vegetable-powder + weekly + 0.7 + + + + http://192.168.2.200:3001/page001 + weekly + 0.7 + + + + http://192.168.2.200:3001/test1 + weekly + 0.7 + + + + http://192.168.2.200:3001/products/mushroom-extracts/organic-snow-mushroom-extract + weekly + 0.7 + + + + http://192.168.2.200:3001/products/fruit-powders/organic-fruit-fiber-organic-super-powder-organic-pure-quality-freeze-dried-extract-blueberry-powder + weekly + 0.7 + + + + http://192.168.2.200:3001/products/fruit-powders/organic-organic-powder-extract-supply-food-grade-freeze-dried-pomegranate-extract-powder + weekly + 0.7 + + + \ No newline at end of file