Skip to content

Commit 12e84c1

Browse files
committed
问题修复
1 parent b393236 commit 12e84c1

14 files changed

Lines changed: 128 additions & 79 deletions

src/App.tsx

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,53 @@ import { Toaster } from "@/components/ui/toaster";
22
import { Toaster as Sonner } from "@/components/ui/sonner";
33
import { TooltipProvider } from "@/components/ui/tooltip";
44
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
5-
import { BrowserRouter, Routes, Route } from "react-router-dom";
5+
import { useEffect } from "react";
6+
import { BrowserRouter, Routes, Route, useLocation } from "react-router-dom";
67
import { HashDownloadRedirect } from "@/components/HashDownloadRedirect";
78
import Index from "./pages/Index";
9+
import Architecture from "./pages/Architecture";
10+
import Contact from "./pages/Contact";
11+
import Demos from "./pages/Demos";
12+
import Products from "./pages/Products";
13+
import Solutions from "./pages/Solutions";
814
import Test from "./pages/Test";
915
import DownloadRedirect from "./pages/DownloadRedirect";
1016
import NotFound from "./pages/NotFound";
1117

1218
const queryClient = new QueryClient();
1319

20+
const ScrollToHash = () => {
21+
const location = useLocation();
22+
23+
useEffect(() => {
24+
if (!location.hash) {
25+
window.scrollTo({ top: 0, behavior: "auto" });
26+
return;
27+
}
28+
29+
window.setTimeout(() => {
30+
document.querySelector(location.hash)?.scrollIntoView({ behavior: "smooth" });
31+
}, 80);
32+
}, [location.pathname, location.hash]);
33+
34+
return null;
35+
};
36+
1437
const App = () => (
1538
<QueryClientProvider client={queryClient}>
1639
<TooltipProvider>
1740
<Toaster />
1841
<Sonner />
1942
<BrowserRouter>
2043
<HashDownloadRedirect />
44+
<ScrollToHash />
2145
<Routes>
2246
<Route path="/" element={<Index />} />
47+
<Route path="/products" element={<Products />} />
48+
<Route path="/solutions" element={<Solutions />} />
49+
<Route path="/architecture" element={<Architecture />} />
50+
<Route path="/demos" element={<Demos />} />
51+
<Route path="/contact" element={<Contact />} />
2352
<Route path="/download" element={<DownloadRedirect />} />
2453
<Route path="/test" element={<Test />} />
2554
{/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}

src/components/DemoVideos.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@ const DemoVideos = () => {
1010

1111
return (
1212
<section id="demos" className="py-24 bg-background">
13-
<div className="container mx-auto px-6">
13+
<div className="container mx-auto px-4 sm:px-6">
1414
<div className="text-center mb-14">
1515
<div className="inline-flex items-center gap-2 rounded-full border border-border/60 bg-muted/40 px-4 py-1.5 text-sm text-muted-foreground mb-4">
1616
<Play className="h-4 w-4 text-primary" />
1717
<span>{t("demos.badge")}</span>
1818
</div>
19-
<h2 className="text-4xl md:text-5xl font-bold mb-4">
19+
<h2 className="mb-4 text-3xl font-bold leading-tight [overflow-wrap:anywhere] md:text-5xl">
2020
{t("demos.title")}
2121
<span className="text-gradient block">{t("demos.titleHighlight")}</span>
2222
</h2>
23-
<p className="text-xl text-muted-foreground max-w-3xl mx-auto mb-8">
23+
<p className="mx-auto mb-8 max-w-3xl text-base leading-8 text-muted-foreground md:text-xl">
2424
{t("demos.subtitle")}
2525
</p>
2626
<Button variant="outline" size="lg" asChild>

src/components/Footer.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { Button } from "@/components/ui/button";
22
import { ExternalLink, Github, Mail, Phone } from "lucide-react";
33
import { useTranslation } from "react-i18next";
44
import { getHomepageLocale, homepageContent } from "@/lib/homepageContent";
5-
import { FLUXMQ_DOC_DEMOS_URL } from "@/lib/constants";
65

76
const Footer = () => {
87
const { i18n } = useTranslation();
@@ -12,7 +11,7 @@ const Footer = () => {
1211
{
1312
title: content.footer.products,
1413
links: [
15-
{ name: "Halia", href: "#products" },
14+
{ name: "Halia", href: "/products#halia" },
1615
{ name: "FluxMQ", href: "https://doc.fluxmq.com", external: true },
1716
{ name: "FCP", href: "https://fcp.doc.fluxmq.com", external: true },
1817
],
@@ -22,14 +21,14 @@ const Footer = () => {
2221
links: [
2322
{ name: "FluxMQ Docs", href: "https://doc.fluxmq.com", external: true },
2423
{ name: "FCP Docs", href: "https://fcp.doc.fluxmq.com", external: true },
25-
{ name: "Demo Videos", href: FLUXMQ_DOC_DEMOS_URL, external: true },
24+
{ name: "Demo Videos", href: "/demos" },
2625
{ name: "GitHub", href: "https://github.com/quickmsg/fluxmq", external: true },
2726
],
2827
},
2928
{
3029
title: content.footer.company,
3130
links: [
32-
{ name: content.nav.contact, href: "#contact" },
31+
{ name: content.nav.contact, href: "/contact" },
3332
{ name: "xurong.lu@fluxmq.com", href: "mailto:xurong.lu@fluxmq.com" },
3433
{ name: "13218040662", href: "tel:13218040662" },
3534
],
@@ -120,7 +119,7 @@ const Footer = () => {
120119
<div className="mt-10 flex flex-col justify-between gap-4 border-t border-border/50 pt-8 text-sm text-muted-foreground md:flex-row md:items-center">
121120
<div>Copyright © 2021-{new Date().getFullYear()} 非迅科技 版权所有 | 苏ICP备2023015068号-1</div>
122121
<div className="flex gap-5">
123-
<a href="#products" className="hover:text-primary">
122+
<a href="/products#halia" className="hover:text-primary">
124123
Halia
125124
</a>
126125
<a href="https://doc.fluxmq.com" target="_blank" rel="noopener noreferrer" className="hover:text-primary">

src/components/Header.tsx

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,34 +38,42 @@ const Header = () => {
3838
const languageLabel = getHomepageLocale(currentLanguage) === "zh" ? "中文" : "English";
3939

4040
const navItems = [
41-
{ label: content.nav.products, href: "#products" },
42-
{ label: content.nav.solutions, href: "#solutions" },
43-
{ label: content.nav.architecture, href: "#architecture" },
44-
{ label: content.nav.performance, href: "#performance" },
41+
{ label: content.nav.products, href: "/products" },
42+
{ label: content.nav.solutions, href: "/solutions" },
43+
{ label: content.nav.architecture, href: "/architecture" },
44+
{ label: content.nav.performance, href: "/architecture#performance" },
4545
];
4646

4747
const docItems = [
4848
{ label: "FluxMQ Docs", href: "https://doc.fluxmq.com" },
4949
{ label: "FCP Docs", href: "https://fcp.doc.fluxmq.com" },
50-
{ label: "Halia", href: "#contact" },
50+
{ label: "Demo Videos", href: "/demos" },
51+
{ label: "Halia", href: "/products#halia" },
5152
];
5253

5354
const openLink = (href: string) => {
54-
if (href.startsWith("#")) {
55+
if (href.startsWith("#") && document.querySelector(href)) {
5556
document.querySelector(href)?.scrollIntoView({ behavior: "smooth" });
5657
setIsMenuOpen(false);
5758
return;
5859
}
60+
if (href.startsWith("/")) {
61+
window.location.assign(href);
62+
setIsMenuOpen(false);
63+
return;
64+
}
5965
window.open(href, "_blank");
6066
};
6167

6268
return (
6369
<header className="fixed left-0 right-0 top-0 z-50 border-b border-border/50 bg-background/82 backdrop-blur-md">
64-
<div className="container mx-auto px-6 py-4">
65-
<nav className="flex items-center justify-between">
66-
<a href="/" className="flex items-center gap-3">
67-
<img src="/feixun.svg" alt="Feixun Tech" className="h-8 w-8 object-contain" />
68-
<span className="text-xl font-bold md:text-2xl">{content.nav.brand}</span>
70+
<div className="container mx-auto px-4 py-4 sm:px-6">
71+
<nav className="flex min-w-0 items-center justify-between">
72+
<a href="/" className="flex min-w-0 items-center gap-3">
73+
<img src="/feixun.svg" alt="Feixun Tech" className="h-8 w-8 shrink-0 object-contain" />
74+
<span className="truncate text-lg font-bold sm:text-xl md:text-2xl">
75+
{content.nav.brand}
76+
</span>
6977
</a>
7078

7179
<div className="hidden items-center gap-7 lg:flex">
@@ -121,15 +129,16 @@ const Header = () => {
121129
<Button variant="ghost" onClick={() => window.open("https://github.com/quickmsg/fluxmq", "_blank")}>
122130
{content.nav.github}
123131
</Button>
124-
<Button variant="hero" onClick={() => openLink("#contact")}>
132+
<Button variant="hero" onClick={() => openLink("/contact")}>
125133
{content.nav.contact}
126134
</Button>
127135
</div>
128136

129137
<Button
130138
variant="ghost"
131139
size="icon"
132-
className="lg:hidden"
140+
className="shrink-0 bg-primary text-primary-foreground shadow-primary hover:bg-primary/90 lg:hidden"
141+
aria-label={isMenuOpen ? "Close navigation" : "Open navigation"}
133142
onClick={() => setIsMenuOpen((open) => !open)}
134143
>
135144
{isMenuOpen ? <X className="h-5 w-5" /> : <Menu className="h-5 w-5" />}
@@ -179,7 +188,7 @@ const Header = () => {
179188
中文
180189
</Button>
181190
</div>
182-
<Button className="mt-3 justify-start" variant="hero" onClick={() => openLink("#contact")}>
191+
<Button className="mt-3 justify-start" variant="hero" onClick={() => openLink("/contact")}>
183192
{content.nav.contact}
184193
</Button>
185194
</div>

src/components/Hero.tsx

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,69 @@
11
import { Button } from "@/components/ui/button";
22
import { ArrowRight, Github, Network } from "lucide-react";
33
import { useTranslation } from "react-i18next";
4-
import heroImage from "@/assets/fluxmq-hero.jpg";
54
import { getHomepageLocale, homepageContent } from "@/lib/homepageContent";
65

76
const Hero = () => {
87
const { i18n } = useTranslation();
98
const content = homepageContent[getHomepageLocale(i18n.language)];
9+
const titleParts = content.hero.title.split("·").map((part) => part.trim());
1010

1111
return (
1212
<section className="relative min-h-[92vh] overflow-hidden border-b border-border/50 pt-28 pb-16">
1313
<div className="absolute inset-0 z-0">
1414
<img
15-
src={heroImage}
15+
src="/site-assets/suite-hero.webp"
1616
alt="Industrial IoT message infrastructure"
17-
className="h-full w-full object-cover opacity-30"
17+
className="h-full w-full object-cover opacity-58"
1818
/>
19-
<div className="absolute inset-0 bg-[linear-gradient(180deg,hsl(var(--background)/0.72)_0%,hsl(var(--background)/0.9)_62%,hsl(var(--background))_100%)]" />
19+
<div className="absolute inset-0 bg-[linear-gradient(90deg,hsl(var(--background)/0.94)_0%,hsl(var(--background)/0.73)_46%,hsl(var(--background)/0.5)_100%)]" />
20+
<div className="absolute inset-0 bg-[linear-gradient(180deg,hsl(var(--background)/0.44)_0%,hsl(var(--background)/0.84)_62%,hsl(var(--background))_100%)]" />
2021
</div>
2122

22-
<div className="container relative z-10 mx-auto px-6">
23-
<div className="mx-auto max-w-5xl text-center">
23+
<div className="container relative z-10 mx-auto px-4 sm:px-6">
24+
<div className="mx-auto max-w-5xl min-w-0 text-center">
2425
<div className="mb-7 inline-flex items-center gap-2 border border-primary/30 bg-background/55 px-4 py-2 text-sm text-muted-foreground backdrop-blur">
2526
<Network className="h-4 w-4 text-primary" />
2627
{content.hero.eyebrow}
2728
</div>
2829

29-
<h1 className="mx-auto max-w-4xl text-5xl font-bold leading-tight md:text-7xl">
30-
{content.hero.title}
30+
<h1 className="mx-auto flex w-full max-w-64 flex-wrap items-center justify-center gap-x-2 gap-y-1 text-3xl font-bold leading-tight sm:max-w-4xl sm:text-5xl md:text-7xl">
31+
{titleParts.map((part, index) => (
32+
<span key={part} className="inline-flex items-center gap-x-2 whitespace-nowrap">
33+
{index > 0 && (
34+
<span className="text-muted-foreground">·</span>
35+
)}
36+
<span>{part}</span>
37+
</span>
38+
))}
3139
</h1>
3240

33-
<p className="mx-auto mt-7 max-w-3xl text-lg leading-8 text-muted-foreground md:text-xl">
41+
<p className="mx-auto mt-7 max-w-[28ch] text-base leading-8 text-muted-foreground [overflow-wrap:anywhere] sm:max-w-3xl md:text-xl">
3442
{content.hero.subtitle}
3543
</p>
3644

3745
<div className="mt-10 flex flex-col items-center justify-center gap-4 sm:flex-row">
3846
<Button
3947
variant="hero"
4048
size="lg"
41-
className="group min-w-44"
42-
onClick={() =>
43-
document.getElementById("contact")?.scrollIntoView({ behavior: "smooth" })
44-
}
49+
className="group w-full max-w-xs min-w-0 sm:w-auto sm:min-w-44"
50+
onClick={() => window.location.assign("/contact")}
4551
>
4652
{content.hero.primaryCta}
4753
<ArrowRight className="h-5 w-5 transition-transform group-hover:translate-x-1" />
4854
</Button>
4955
<Button
5056
variant="glass"
5157
size="lg"
52-
className="min-w-44"
53-
onClick={() =>
54-
document.getElementById("products")?.scrollIntoView({ behavior: "smooth" })
55-
}
58+
className="w-full max-w-xs min-w-0 sm:w-auto sm:min-w-44"
59+
onClick={() => window.location.assign("/products")}
5660
>
5761
{content.hero.secondaryCta}
5862
</Button>
5963
<Button
6064
variant="outline"
6165
size="lg"
62-
className="min-w-44 border-primary/30 bg-background/40"
66+
className="w-full max-w-xs min-w-0 border-primary/30 bg-background/40 sm:w-auto sm:min-w-44"
6367
onClick={() => window.open("https://github.com/quickmsg/fluxmq", "_blank")}
6468
>
6569
<Github className="h-5 w-5" />

src/components/IndustrySolutions.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ const IndustrySolutions = () => {
88

99
return (
1010
<section id="solutions" className="bg-secondary/25 py-24">
11-
<div className="container mx-auto px-6">
11+
<div className="container mx-auto px-4 sm:px-6">
1212
<div className="mx-auto mb-14 max-w-3xl text-center">
1313
<p className="mb-3 text-sm font-semibold uppercase tracking-normal text-primary">
1414
{content.solutions.eyebrow}
1515
</p>
16-
<h2 className="text-4xl font-bold leading-tight md:text-5xl">
16+
<h2 className="text-3xl font-bold leading-tight [overflow-wrap:anywhere] md:text-5xl">
1717
{content.solutions.title}
1818
</h2>
19-
<p className="mt-5 text-lg leading-8 text-muted-foreground">
19+
<p className="mx-auto mt-5 max-w-[29ch] text-base leading-8 text-muted-foreground [overflow-wrap:anywhere] sm:max-w-none md:text-lg">
2020
{content.solutions.subtitle}
2121
</p>
2222
</div>

src/components/Performance.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,13 @@ const Performance = () => {
3838

3939
return (
4040
<section id="performance" className="py-24">
41-
<div className="container mx-auto px-6">
41+
<div className="container mx-auto px-4 sm:px-6">
4242
<div className="text-center mb-16">
43-
<h2 className="text-4xl md:text-5xl font-bold mb-6">
43+
<h2 className="mb-6 text-3xl font-bold leading-tight [overflow-wrap:anywhere] md:text-5xl">
4444
{t('performance.title')}
4545
<span className="text-gradient block">{t('performance.titleHighlight')}</span>
4646
</h2>
47-
<p className="text-xl text-muted-foreground max-w-3xl mx-auto">
47+
<p className="mx-auto max-w-3xl text-base leading-8 text-muted-foreground md:text-xl">
4848
{t('performance.subtitle')}
4949
</p>
5050
</div>

src/components/PlatformArchitecture.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@ const PlatformArchitecture = () => {
99

1010
return (
1111
<section id="architecture" className="border-y border-border/50 bg-secondary/25 py-24">
12-
<div className="container mx-auto px-6">
12+
<div className="container mx-auto px-4 sm:px-6">
1313
<div className="grid grid-cols-1 gap-12 lg:grid-cols-[0.9fr_1.1fr] lg:items-center">
1414
<div>
1515
<p className="mb-3 text-sm font-semibold uppercase tracking-normal text-primary">
1616
{content.architecture.eyebrow}
1717
</p>
18-
<h2 className="text-4xl font-bold leading-tight md:text-5xl">
18+
<h2 className="text-3xl font-bold leading-tight [overflow-wrap:anywhere] md:text-5xl">
1919
{content.architecture.title}
2020
</h2>
21-
<p className="mt-5 text-lg leading-8 text-muted-foreground">
21+
<p className="mt-5 max-w-[29ch] text-base leading-8 text-muted-foreground [overflow-wrap:anywhere] sm:max-w-none md:text-lg">
2222
{content.architecture.subtitle}
2323
</p>
2424

@@ -34,7 +34,9 @@ const PlatformArchitecture = () => {
3434
<SignalIcon className="mt-1 h-5 w-5 shrink-0 text-primary" />
3535
<div>
3636
<div className="font-semibold">{signal.label}</div>
37-
<div className="mt-1 text-sm text-muted-foreground">{signal.value}</div>
37+
<div className="mt-1 text-sm text-muted-foreground [overflow-wrap:anywhere]">
38+
{signal.value}
39+
</div>
3840
</div>
3941
</div>
4042
);

src/components/ProductShowcase.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ const ProductShowcase = () => {
1010

1111
return (
1212
<section id="products" className="bg-background py-24">
13-
<div className="container mx-auto px-6">
14-
<div className="mb-14 max-w-3xl">
13+
<div className="container mx-auto px-4 sm:px-6">
14+
<div className="mb-14 max-w-3xl min-w-0">
1515
<p className="mb-3 text-sm font-semibold uppercase tracking-normal text-primary">
1616
{content.products.eyebrow}
1717
</p>
18-
<h2 className="text-4xl font-bold leading-tight md:text-5xl">
18+
<h2 className="text-3xl font-bold leading-tight [overflow-wrap:anywhere] md:text-5xl">
1919
{content.products.title}
2020
</h2>
21-
<p className="mt-5 text-lg leading-8 text-muted-foreground">
21+
<p className="mt-5 max-w-[29ch] text-base leading-8 text-muted-foreground [overflow-wrap:anywhere] sm:max-w-none md:text-lg">
2222
{content.products.subtitle}
2323
</p>
2424
</div>
@@ -30,6 +30,7 @@ const ProductShowcase = () => {
3030
return (
3131
<Card
3232
key={product.id}
33+
id={product.id}
3334
className="group flex h-full flex-col overflow-hidden border-border/70 bg-card/80 shadow-card transition-colors hover:border-primary/60"
3435
>
3536
<CardHeader className="pb-5">
@@ -85,6 +86,10 @@ const ProductShowcase = () => {
8586
?.scrollIntoView({ behavior: "smooth" });
8687
return;
8788
}
89+
if (product.href.startsWith("/")) {
90+
window.location.assign(product.href);
91+
return;
92+
}
8893
window.open(product.href, "_blank");
8994
}}
9095
>

0 commit comments

Comments
 (0)