@allbluecn/web-app 0.17.0 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/components/landing/landing-page.tsx +20 -0
- package/src/lib/changelog/sdk-versions.ts +1 -1
- package/src/paraglide/README.md +1 -1
- package/src/paraglide/messages/_index.js +0 -48
- package/src/paraglide/messages/en.js +0 -15
- package/src/paraglide/messages/zh.js +0 -15
- package/src/routes/_nav/prd/index.tsx +1 -1
- package/src/routes/_nav/tags/index.tsx +1 -1
- package/src/routes/_public/index/route.tsx +2 -6
- package/src/server/middlewares/paraglide-locale.ts +39 -0
- package/src/start.ts +4 -1
- package/src/styles/globals.css +2 -3
- package/src/__tests__/bench/baselines/format-timestamp.json +0 -44
- package/src/assets/logo/logo.tsx +0 -70
- package/src/components/shadcn-space/animations/marquee.tsx +0 -139
- package/src/components/shadcn-space/blocks/about-us-01/about-us.tsx +0 -136
- package/src/components/shadcn-space/blocks/about-us-01/index.tsx +0 -62
- package/src/components/shadcn-space/blocks/cta-01/cta.tsx +0 -74
- package/src/components/shadcn-space/blocks/faq-01/faq.tsx +0 -100
- package/src/components/shadcn-space/blocks/footer-01/footer.tsx +0 -232
- package/src/components/shadcn-space/blocks/hero-01/brand-slider.tsx +0 -79
- package/src/components/shadcn-space/blocks/hero-01/header.tsx +0 -272
- package/src/components/shadcn-space/blocks/hero-01/hero.tsx +0 -111
- package/src/components/shadcn-space/blocks/hero-01/index.tsx +0 -127
- package/src/components/shadcn-space/blocks/portfolio-01/portfolio.tsx +0 -149
- package/src/components/shadcn-space/blocks/pricing-01/pricing.tsx +0 -187
- package/src/components/shadcn-space/blocks/pricing-02/pricing.tsx +0 -213
- package/src/components/shadcn-space/blocks/services-01/services.tsx +0 -178
- package/src/components/shadcn-space/blocks/team-01/team.tsx +0 -166
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
-
// AllBlue - 理想之海
|
|
3
|
-
// Copyright (C) 2026 AllBlue Contributors
|
|
4
|
-
//
|
|
5
|
-
// This program is free software: you can redistribute it and/or modify
|
|
6
|
-
// it under the terms of the GNU Affero General Public License as published by
|
|
7
|
-
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
// (at your option) any later version.
|
|
9
|
-
//
|
|
10
|
-
// This program is distributed in the hope that it will be useful,
|
|
11
|
-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
// GNU Affero General Public License for more details.
|
|
14
|
-
//
|
|
15
|
-
// You should have received a copy of the GNU Affero General Public License
|
|
16
|
-
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
-
|
|
18
|
-
import { cn } from "@/lib/utils";
|
|
19
|
-
import { LucideIcon, Plus } from "lucide-react";
|
|
20
|
-
import { useEffect, useRef } from "react";
|
|
21
|
-
import { m, useSpring, useTransform, useInView } from "motion/react";
|
|
22
|
-
type aboutusData = {
|
|
23
|
-
icon: LucideIcon;
|
|
24
|
-
title: string;
|
|
25
|
-
color: string;
|
|
26
|
-
}[];
|
|
27
|
-
type statisticsCounter = {
|
|
28
|
-
title: string;
|
|
29
|
-
count: number;
|
|
30
|
-
}[];
|
|
31
|
-
const AnimatedCounter = ({
|
|
32
|
-
value,
|
|
33
|
-
isInView,
|
|
34
|
-
}: {
|
|
35
|
-
value: number;
|
|
36
|
-
isInView: boolean;
|
|
37
|
-
}) => {
|
|
38
|
-
const springValue = useSpring(0, {
|
|
39
|
-
bounce: 0,
|
|
40
|
-
duration: 2000,
|
|
41
|
-
});
|
|
42
|
-
const displayValue = useTransform(springValue, (current) =>
|
|
43
|
-
Math.round(current)
|
|
44
|
-
);
|
|
45
|
-
useEffect(() => {
|
|
46
|
-
if (isInView) {
|
|
47
|
-
springValue.set(value);
|
|
48
|
-
}
|
|
49
|
-
}, [isInView, value, springValue]);
|
|
50
|
-
return <m.span>{displayValue}</m.span>;
|
|
51
|
-
};
|
|
52
|
-
const AboutUs = ({
|
|
53
|
-
aboutusData,
|
|
54
|
-
statisticsCounter,
|
|
55
|
-
}: {
|
|
56
|
-
aboutusData: aboutusData;
|
|
57
|
-
statisticsCounter: statisticsCounter;
|
|
58
|
-
}) => {
|
|
59
|
-
const statsRef = useRef(null);
|
|
60
|
-
const isInView = useInView(statsRef, { once: true, margin: "-100px" });
|
|
61
|
-
return (
|
|
62
|
-
<section className="lg:py-20 sm:py-16 py-8">
|
|
63
|
-
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-16">
|
|
64
|
-
<div className="flex flex-col items-center justify-center gap-8 md:gap-16">
|
|
65
|
-
<m.div
|
|
66
|
-
initial={{ y: -40, opacity: 0 }}
|
|
67
|
-
whileInView={{ y: 0, opacity: 1 }}
|
|
68
|
-
viewport={{ once: true }}
|
|
69
|
-
transition={{
|
|
70
|
-
duration: 0.8,
|
|
71
|
-
ease: [0.21, 0.47, 0.32, 0.98],
|
|
72
|
-
}}
|
|
73
|
-
className="flex flex-col items-center justify-center gap-4"
|
|
74
|
-
>
|
|
75
|
-
<h2 className="text-3xl sm:text-4xl lg:text-5xl font-medium text-foreground text-center tracking-tight">
|
|
76
|
-
Crafting exceptional, well experienced & technology driven
|
|
77
|
-
strategies to drive impactful results with
|
|
78
|
-
</h2>
|
|
79
|
-
<div className="flex flex-wrap items-center justify-center gap-x-2 gap-y-4">
|
|
80
|
-
{aboutusData.map((item, index) => (
|
|
81
|
-
<div
|
|
82
|
-
key={index}
|
|
83
|
-
className={cn(
|
|
84
|
-
"flex items-center gap-3 px-6 py-2 rounded-full",
|
|
85
|
-
item.color
|
|
86
|
-
)}
|
|
87
|
-
>
|
|
88
|
-
<item.icon className="w-6 h-6 sm:w-8 sm:h-8 lg:w-10 lg:h-10" />
|
|
89
|
-
<span
|
|
90
|
-
className={cn(
|
|
91
|
-
"text-4xl font-normal",
|
|
92
|
-
"font-serif"
|
|
93
|
-
)}
|
|
94
|
-
>
|
|
95
|
-
{item.title}
|
|
96
|
-
</span>
|
|
97
|
-
</div>
|
|
98
|
-
))}
|
|
99
|
-
</div>
|
|
100
|
-
</m.div>
|
|
101
|
-
<div
|
|
102
|
-
ref={statsRef}
|
|
103
|
-
className="w-full grid grid-cols-1 sm:grid-cols-3 gap-1 sm:gap-0"
|
|
104
|
-
>
|
|
105
|
-
{statisticsCounter?.map((value, index) => {
|
|
106
|
-
return (
|
|
107
|
-
<div
|
|
108
|
-
key={index}
|
|
109
|
-
className="relative px-6 py-5 sm:py-10 gap-3 flex flex-col items-center justify-center"
|
|
110
|
-
>
|
|
111
|
-
{index !== 0 && (
|
|
112
|
-
<div className="hidden sm:block absolute left-0 top-1/2 -translate-y-1/2 w-px h-40 bg-border" />
|
|
113
|
-
)}
|
|
114
|
-
<div className="flex gap-0 sm:gap-2 text-6xl sm:text-7xl md:text-8xl lg:text-9xl font-medium">
|
|
115
|
-
<Plus
|
|
116
|
-
strokeWidth={3.5}
|
|
117
|
-
className="w-6 h-6 sm:w-8 sm:h-8 lg:w-12 lg:h-12"
|
|
118
|
-
/>
|
|
119
|
-
<AnimatedCounter
|
|
120
|
-
value={value.count}
|
|
121
|
-
isInView={isInView}
|
|
122
|
-
/>
|
|
123
|
-
</div>
|
|
124
|
-
<p className="text-base font-normal text-muted-foreground text-center">
|
|
125
|
-
{value.title}
|
|
126
|
-
</p>
|
|
127
|
-
</div>
|
|
128
|
-
);
|
|
129
|
-
})}
|
|
130
|
-
</div>
|
|
131
|
-
</div>
|
|
132
|
-
</div>
|
|
133
|
-
</section>
|
|
134
|
-
);
|
|
135
|
-
};
|
|
136
|
-
export default AboutUs;
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
-
// AllBlue - 理想之海
|
|
3
|
-
// Copyright (C) 2026 AllBlue Contributors
|
|
4
|
-
//
|
|
5
|
-
// This program is free software: you can redistribute it and/or modify
|
|
6
|
-
// it under the terms of the GNU Affero General Public License as published by
|
|
7
|
-
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
// (at your option) any later version.
|
|
9
|
-
//
|
|
10
|
-
// This program is distributed in the hope that it will be useful,
|
|
11
|
-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
// GNU Affero General Public License for more details.
|
|
14
|
-
//
|
|
15
|
-
// You should have received a copy of the GNU Affero General Public License
|
|
16
|
-
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
-
|
|
18
|
-
import AboutUs from "@/components/shadcn-space/blocks/about-us-01/about-us";
|
|
19
|
-
import { Target, WandSparkles, Zap } from "lucide-react";
|
|
20
|
-
|
|
21
|
-
const aboutusData = [
|
|
22
|
-
{
|
|
23
|
-
icon: WandSparkles,
|
|
24
|
-
title: "Creativity",
|
|
25
|
-
color: "bg-blue-500/10 text-blue-500"
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
icon: Zap,
|
|
29
|
-
title: "Innovation",
|
|
30
|
-
color: "bg-teal-400/10 text-teal-400"
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
icon: Target,
|
|
34
|
-
title: "Strategy",
|
|
35
|
-
color: "bg-orange-400/10 text-orange-400"
|
|
36
|
-
}
|
|
37
|
-
];
|
|
38
|
-
|
|
39
|
-
const statisticsCounter = [
|
|
40
|
-
{
|
|
41
|
-
title: "Total Projects Completed",
|
|
42
|
-
count: 40
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
title: "Years of Experience",
|
|
46
|
-
count: 15
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
title: "Design Awards",
|
|
50
|
-
count: 12
|
|
51
|
-
},
|
|
52
|
-
]
|
|
53
|
-
|
|
54
|
-
const AboutAndStats01 = () => {
|
|
55
|
-
return (
|
|
56
|
-
<>
|
|
57
|
-
<AboutUs aboutusData={aboutusData} statisticsCounter={statisticsCounter} />
|
|
58
|
-
</>
|
|
59
|
-
);
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
export default AboutAndStats01;
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
-
// AllBlue - 理想之海
|
|
3
|
-
// Copyright (C) 2026 AllBlue Contributors
|
|
4
|
-
//
|
|
5
|
-
// This program is free software: you can redistribute it and/or modify
|
|
6
|
-
// it under the terms of the GNU Affero General Public License as published by
|
|
7
|
-
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
// (at your option) any later version.
|
|
9
|
-
//
|
|
10
|
-
// This program is distributed in the hope that it will be useful,
|
|
11
|
-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
// GNU Affero General Public License for more details.
|
|
14
|
-
//
|
|
15
|
-
// You should have received a copy of the GNU Affero General Public License
|
|
16
|
-
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
-
|
|
18
|
-
import { useRef } from "react";
|
|
19
|
-
import { m } from "motion/react";
|
|
20
|
-
import { Button } from "@/components/ui/button";
|
|
21
|
-
import { ArrowUpRight } from "lucide-react";
|
|
22
|
-
|
|
23
|
-
type CTAProps = {
|
|
24
|
-
className?: string;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const CTA = ({ className }: CTAProps) => {
|
|
28
|
-
const ref = useRef(null);
|
|
29
|
-
|
|
30
|
-
const bottomAnimation = {
|
|
31
|
-
initial: { y: "5%", opacity: 0 },
|
|
32
|
-
animate: { y: 0, opacity: 1 },
|
|
33
|
-
transition: { duration: 1, delay: 0.8 },
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
return (
|
|
37
|
-
<section>
|
|
38
|
-
<div className="sm:py-20 py-8">
|
|
39
|
-
<div className="max-w-7xl mx-auto sm:px-16 px-4">
|
|
40
|
-
<div
|
|
41
|
-
ref={ref}
|
|
42
|
-
className="relative overflow-hidden min-h-96 flex items-center justify-center px-6 border border-border rounded-3xl before:absolute before:w-full before:h-4/5 before:bg-linear-to-r before:from-sky-100 before:from-15% before:via-white before:via-55% before:to-amber-100 before:to-90% before:rounded-full before:top-24 before:blur-3xl before:-z-10 dark:before:from-sky-400/10 dark:before:from-40% dark:before:via-black dark:before:via-55% dark:before:to-amber-300/10 dark:before:to-60% dark:before:rounded-full dark:before:-z-10"
|
|
43
|
-
>
|
|
44
|
-
<m.div
|
|
45
|
-
{...bottomAnimation}
|
|
46
|
-
className="flex flex-col gap-6 items-center mx-auto"
|
|
47
|
-
>
|
|
48
|
-
<div className="flex flex-col gap-3 items-center text-center">
|
|
49
|
-
<h2 className="text-3xl md:text-5xl font-medium">
|
|
50
|
-
Innovative solutions for bold brands
|
|
51
|
-
</h2>
|
|
52
|
-
<p className="max-w-2xl mx-auto">
|
|
53
|
-
Looking to elevate your brand? We craft immersive experiences
|
|
54
|
-
that captivate, engage, and make your business unforgettable
|
|
55
|
-
in every interaction.
|
|
56
|
-
</p>
|
|
57
|
-
</div>
|
|
58
|
-
<Button className="relative text-sm font-medium rounded-full h-12 p-1 ps-6 pe-14 group transition-all duration-500 hover:ps-14 hover:pe-6 w-fit overflow-hidden hover:bg-primary/80 cursor-pointer">
|
|
59
|
-
<span className="relative z-10 transition-all duration-500">
|
|
60
|
-
Let's craft together
|
|
61
|
-
</span>
|
|
62
|
-
<div className="absolute right-1 w-10 h-10 bg-background text-foreground rounded-full flex items-center justify-center transition-all duration-500 group-hover:right-[calc(100%-44px)] group-hover:rotate-45">
|
|
63
|
-
<ArrowUpRight size={16} />
|
|
64
|
-
</div>
|
|
65
|
-
</Button>
|
|
66
|
-
</m.div>
|
|
67
|
-
</div>
|
|
68
|
-
</div>
|
|
69
|
-
</div>
|
|
70
|
-
</section>
|
|
71
|
-
);
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
export default CTA;
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
-
// AllBlue - 理想之海
|
|
3
|
-
// Copyright (C) 2026 AllBlue Contributors
|
|
4
|
-
//
|
|
5
|
-
// This program is free software: you can redistribute it and/or modify
|
|
6
|
-
// it under the terms of the GNU Affero General Public License as published by
|
|
7
|
-
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
// (at your option) any later version.
|
|
9
|
-
//
|
|
10
|
-
// This program is distributed in the hope that it will be useful,
|
|
11
|
-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
// GNU Affero General Public License for more details.
|
|
14
|
-
//
|
|
15
|
-
// You should have received a copy of the GNU Affero General Public License
|
|
16
|
-
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
-
|
|
18
|
-
import {
|
|
19
|
-
Accordion,
|
|
20
|
-
AccordionContent,
|
|
21
|
-
AccordionItem,
|
|
22
|
-
AccordionTrigger,
|
|
23
|
-
} from "@/components/ui/accordion";
|
|
24
|
-
import { Badge } from "@/components/ui/badge";
|
|
25
|
-
import { PlusIcon } from "lucide-react";
|
|
26
|
-
import { cn } from "@/lib/utils";
|
|
27
|
-
|
|
28
|
-
const FAQ_DATA = [
|
|
29
|
-
{
|
|
30
|
-
question: "What services does Shadcn Space offer?",
|
|
31
|
-
answer:
|
|
32
|
-
"We offer a wide range of services including web development, app development, and digital marketing.",
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
question: "How long does a typical project take?",
|
|
36
|
-
answer:
|
|
37
|
-
"The time it takes to complete a project depends on the complexity of the project and the scope of the work.",
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
question: "How is pricing structured at Awake Agency?",
|
|
41
|
-
answer:
|
|
42
|
-
"Pricing is based on the complexity of the project and the scope of the work.",
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
question: "Do you offer ongoing support after project completion?",
|
|
46
|
-
answer:
|
|
47
|
-
"Absolutely! We offer comprehensive post-launch support to ensure a seamless implementation and provide ongoing maintenance packages tailored to clients who need regular updates or technical assistance. Our commitment doesn’t end at launch — we’re here to help you every step of the way.",
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
question: "How often will I receive updates on my project?",
|
|
51
|
-
answer:
|
|
52
|
-
"We provide updates on a regular basis to ensure that your project is running smoothly and that you are aware of any changes or updates to the project.",
|
|
53
|
-
},
|
|
54
|
-
];
|
|
55
|
-
|
|
56
|
-
export default function Faq() {
|
|
57
|
-
return (
|
|
58
|
-
<section>
|
|
59
|
-
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 xl:py-24 py-8 flex flex-col gap-16">
|
|
60
|
-
<div className="flex flex-col gap-4 items-center animate-in fade-in slide-in-from-top-10 duration-1000 delay-100 ease-in-out fill-mode-both">
|
|
61
|
-
<Badge
|
|
62
|
-
variant="outline"
|
|
63
|
-
className="text-sm h-auto py-1 px-3 border-0 outline outline-border"
|
|
64
|
-
>
|
|
65
|
-
FAQs
|
|
66
|
-
</Badge>
|
|
67
|
-
<h2 className="text-5xl font-medium text-center max-w-lg">
|
|
68
|
-
Got questions? We’ve got answers ready
|
|
69
|
-
</h2>
|
|
70
|
-
</div>
|
|
71
|
-
<div>
|
|
72
|
-
<Accordion className="w-full flex flex-col gap-6">
|
|
73
|
-
{FAQ_DATA.map((faq, index) => (
|
|
74
|
-
<AccordionItem
|
|
75
|
-
key={`item-${index}`}
|
|
76
|
-
value={`item-${index}`}
|
|
77
|
-
className={cn(
|
|
78
|
-
"p-6 border border-border rounded-2xl flex flex-col gap-3 group/item data-[open]:bg-accent transition-colors animate-in fade-in slide-in-from-bottom-8 duration-700 fill-mode-both",
|
|
79
|
-
index === 0 && "delay-100",
|
|
80
|
-
index === 1 && "delay-200",
|
|
81
|
-
index === 2 && "delay-300",
|
|
82
|
-
index === 3 && "delay-400",
|
|
83
|
-
index === 4 && "delay-500",
|
|
84
|
-
)}
|
|
85
|
-
>
|
|
86
|
-
<AccordionTrigger className="p-0 text-xl font-medium hover:no-underline **:data-[slot=accordion-trigger-icon]:hidden cursor-pointer">
|
|
87
|
-
{faq.question}
|
|
88
|
-
<PlusIcon className="w-6 h-6 shrink-0 transition-transform duration-200 group-aria-expanded/accordion-trigger:rotate-45" />
|
|
89
|
-
</AccordionTrigger>
|
|
90
|
-
<AccordionContent className="p-0 text-muted-foreground text-base">
|
|
91
|
-
{faq.answer}
|
|
92
|
-
</AccordionContent>
|
|
93
|
-
</AccordionItem>
|
|
94
|
-
))}
|
|
95
|
-
</Accordion>
|
|
96
|
-
</div>
|
|
97
|
-
</div>
|
|
98
|
-
</section>
|
|
99
|
-
);
|
|
100
|
-
}
|
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
-
// AllBlue - 理想之海
|
|
3
|
-
// Copyright (C) 2026 AllBlue Contributors
|
|
4
|
-
//
|
|
5
|
-
// This program is free software: you can redistribute it and/or modify
|
|
6
|
-
// it under the terms of the GNU Affero General Public License as published by
|
|
7
|
-
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
// (at your option) any later version.
|
|
9
|
-
//
|
|
10
|
-
// This program is distributed in the hope that it will be useful,
|
|
11
|
-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
// GNU Affero General Public License for more details.
|
|
14
|
-
//
|
|
15
|
-
// You should have received a copy of the GNU Affero General Public License
|
|
16
|
-
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
-
|
|
18
|
-
import Logo from "@/assets/logo/logo";
|
|
19
|
-
import { Separator } from "@/components/ui/separator";
|
|
20
|
-
|
|
21
|
-
const TwitterIcon = () => (
|
|
22
|
-
<svg width="20" height="20" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
23
|
-
<path d="M11.791 2.188 8.46 5.996 5.58 2.188H1.408l4.984 6.518-4.723 5.399H3.69l3.646-4.166 3.187 4.166h4.068l-5.196-6.87 4.417-5.047zm-.71 10.707L3.77 3.335h1.2l7.23 9.56z" fill="currentColor" />
|
|
24
|
-
</svg>
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
const LinkedinIcon = () => (
|
|
28
|
-
<svg width="20" height="20" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
29
|
-
<g clipPath="url(#footer01-linkedin-clip)">
|
|
30
|
-
<path d="M13.633 13.633h-2.37V9.92c0-.885-.017-2.025-1.234-2.025-1.235 0-1.424.965-1.424 1.96v3.778h-2.37V5.998H8.51v1.043h.031a2.5 2.5 0 0 1 2.246-1.233c2.403 0 2.846 1.58 2.846 3.637zM3.56 4.954a1.376 1.376 0 1 1 0-2.751 1.376 1.376 0 0 1 0 2.751m1.185 8.679H2.372V5.998h2.373zM14.815.001H1.18A1.17 1.17 0 0 0 0 1.154v13.691A1.17 1.17 0 0 0 1.18 16h13.635A1.17 1.17 0 0 0 16 14.845V1.153A1.17 1.17 0 0 0 14.815 0" fill="currentColor" />
|
|
31
|
-
</g>
|
|
32
|
-
<defs>
|
|
33
|
-
<clipPath id="footer01-linkedin-clip">
|
|
34
|
-
<path d="M0 0h16v16H0z" />
|
|
35
|
-
</clipPath>
|
|
36
|
-
</defs>
|
|
37
|
-
</svg>
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
const DribbbleIcon = () => (
|
|
41
|
-
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
42
|
-
<g clipPath="url(#footer01-dribbble-clip)">
|
|
43
|
-
<path d="M15.942 4.242C12.683 7.617 8.333 8.7 1.874 9.117m16.25 1.583c-5.517-1.175-10.117.833-13.65 5.267M7.133 2.292c3.642 5 5 7.85 6.667 14.766M18.333 10a8.333 8.333 0 1 1-16.666 0 8.333 8.333 0 0 1 16.666 0" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
|
44
|
-
</g>
|
|
45
|
-
<defs>
|
|
46
|
-
<clipPath id="footer01-dribbble-clip">
|
|
47
|
-
<path fill="currentColor" d="M0 0h20v20H0z" />
|
|
48
|
-
</clipPath>
|
|
49
|
-
</defs>
|
|
50
|
-
</svg>
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
const InstagramIcon = () => (
|
|
54
|
-
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
55
|
-
<g clipPath="url(#footer01-instagram-clip)">
|
|
56
|
-
<path d="M12 2.162c3.204 0 3.584.012 4.849.07 1.17.054 1.805.249 2.228.413.56.218.96.478 1.38.898s.68.82.898 1.38c.164.423.36 1.058.413 2.228.058 1.265.07 1.645.07 4.849s-.012 3.584-.07 4.849c-.053 1.17-.249 1.805-.413 2.228a3.7 3.7 0 0 1-.898 1.38c-.42.42-.82.68-1.38.898-.423.164-1.058.36-2.228.413-1.265.058-1.645.07-4.849.07s-3.584-.012-4.849-.07c-1.17-.053-1.805-.249-2.228-.413a3.7 3.7 0 0 1-1.38-.898c-.42-.42-.68-.82-.898-1.38-.164-.423-.36-1.058-.413-2.228-.058-1.265-.07-1.645-.07-4.849s.012-3.584.07-4.849c.054-1.17.249-1.805.413-2.228.218-.56.478-.96.898-1.38s.82-.68 1.38-.898c.423-.164 1.058-.36 2.228-.413 1.265-.058 1.645-.07 4.849-.07M12 0C8.741 0 8.332.014 7.052.072 5.775.131 4.902.333 4.14.63a5.9 5.9 0 0 0-2.126 1.384A5.9 5.9 0 0 0 .63 4.14c-.297.763-.5 1.635-.558 2.912C.014 8.332 0 8.741 0 12s.014 3.668.072 4.948c.059 1.277.261 2.15.558 2.912.307.79.717 1.459 1.384 2.126A5.9 5.9 0 0 0 4.14 23.37c.763.297 1.635.5 2.912.558C8.332 23.986 8.741 24 12 24s3.668-.014 4.948-.072c1.277-.059 2.15-.261 2.912-.558a5.9 5.9 0 0 0 2.126-1.384 5.9 5.9 0 0 0 1.384-2.126c.297-.763.5-1.635.558-2.912.058-1.28.072-1.689.072-4.948s-.014-3.668-.072-4.948c-.059-1.277-.261-2.15-.558-2.912a5.9 5.9 0 0 0-1.384-2.126A5.9 5.9 0 0 0 19.86.63c-.763-.297-1.635-.5-2.912-.558C15.668.014 15.259 0 12 0m0 5.838a6.162 6.162 0 1 0 0 12.324 6.162 6.162 0 0 0 0-12.324M12 16a4 4 0 1 1 0-8 4 4 0 0 1 0 8m7.846-10.406a1.44 1.44 0 1 1-2.88 0 1.44 1.44 0 0 1 2.88 0" fill="currentColor" />
|
|
57
|
-
</g>
|
|
58
|
-
<defs>
|
|
59
|
-
<clipPath id="footer01-instagram-clip">
|
|
60
|
-
<path fill="currentColor" d="M0 0h24v24H0z" />
|
|
61
|
-
</clipPath>
|
|
62
|
-
</defs>
|
|
63
|
-
</svg>
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
type FooterData = {
|
|
67
|
-
title: string;
|
|
68
|
-
links: {
|
|
69
|
-
title: string;
|
|
70
|
-
href: string;
|
|
71
|
-
}[];
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
const footerSections: FooterData[] = [
|
|
75
|
-
{
|
|
76
|
-
title: "Sitemap",
|
|
77
|
-
links: [
|
|
78
|
-
{
|
|
79
|
-
title: "Contact us",
|
|
80
|
-
href: "#",
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
title: "About us",
|
|
84
|
-
href: "#",
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
title: "Work",
|
|
88
|
-
href: "#",
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
title: "Services",
|
|
92
|
-
href: "#",
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
title: "Pricing",
|
|
96
|
-
href: "#",
|
|
97
|
-
},
|
|
98
|
-
],
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
title: "Other Pages",
|
|
102
|
-
links: [
|
|
103
|
-
{
|
|
104
|
-
title: "Error 404",
|
|
105
|
-
href: "#",
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
title: "Terms & Conditions",
|
|
109
|
-
href: "#",
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
title: "Privacy Policy",
|
|
113
|
-
href: "#",
|
|
114
|
-
},
|
|
115
|
-
],
|
|
116
|
-
},
|
|
117
|
-
];
|
|
118
|
-
|
|
119
|
-
const Footer = () => {
|
|
120
|
-
return (
|
|
121
|
-
<footer className="py-10">
|
|
122
|
-
<div className="max-w-7xl xl:px-16 lg:px-8 px-4 mx-auto">
|
|
123
|
-
<div className="flex flex-col gap-6 sm:gap-12">
|
|
124
|
-
<div className="py-12 grid grid-cols-2 sm:grid-cols-4 md:grid-cols-7 lg:grid-cols-12 gap-x-8 gap-y-10 px-6 xl:px-0">
|
|
125
|
-
<div className="col-span-full lg:col-span-4">
|
|
126
|
-
<div className="flex flex-col gap-6 animate-in fade-in slide-in-from-bottom-10 duration-1000 delay-100 ease-in-out fill-mode-both">
|
|
127
|
-
{/* Logo */}
|
|
128
|
-
<a href="#">
|
|
129
|
-
<Logo />
|
|
130
|
-
</a>
|
|
131
|
-
|
|
132
|
-
<p className="text-base font-normal text-muted-foreground">
|
|
133
|
-
Empowering businesses with innovative solutions. Let's create
|
|
134
|
-
something amazing together.
|
|
135
|
-
</p>
|
|
136
|
-
|
|
137
|
-
{/* social links */}
|
|
138
|
-
<div className="flex items-center gap-4">
|
|
139
|
-
<a
|
|
140
|
-
href="#"
|
|
141
|
-
className="text-muted-foreground hover:text-foreground"
|
|
142
|
-
>
|
|
143
|
-
<TwitterIcon />
|
|
144
|
-
</a>
|
|
145
|
-
<a
|
|
146
|
-
href="#"
|
|
147
|
-
className="text-muted-foreground hover:text-foreground"
|
|
148
|
-
>
|
|
149
|
-
<LinkedinIcon />
|
|
150
|
-
</a>
|
|
151
|
-
<a
|
|
152
|
-
href="#"
|
|
153
|
-
className="text-muted-foreground hover:text-foreground"
|
|
154
|
-
>
|
|
155
|
-
<DribbbleIcon />
|
|
156
|
-
</a>
|
|
157
|
-
<a
|
|
158
|
-
href="#"
|
|
159
|
-
className="text-muted-foreground hover:text-foreground"
|
|
160
|
-
>
|
|
161
|
-
<InstagramIcon />
|
|
162
|
-
</a>
|
|
163
|
-
</div>
|
|
164
|
-
</div>
|
|
165
|
-
</div>
|
|
166
|
-
|
|
167
|
-
<div className="col-span-1 lg:block hidden"></div>
|
|
168
|
-
|
|
169
|
-
{footerSections.map(({ title, links }, index) => (
|
|
170
|
-
<div key={index} className="col-span-2">
|
|
171
|
-
<div className="flex flex-col gap-4 animate-in fade-in slide-in-from-bottom-10 duration-1000 delay-100 ease-in-out fill-mode-both">
|
|
172
|
-
<p className="text-base font-medium text-foreground">
|
|
173
|
-
{title}
|
|
174
|
-
</p>
|
|
175
|
-
<ul className="flex flex-col gap-3">
|
|
176
|
-
{links.map(({ title, href }) => (
|
|
177
|
-
<li key={title}>
|
|
178
|
-
<a
|
|
179
|
-
href={href}
|
|
180
|
-
className="text-base font-normal text-muted-foreground hover:text-foreground"
|
|
181
|
-
>
|
|
182
|
-
{title}
|
|
183
|
-
</a>
|
|
184
|
-
</li>
|
|
185
|
-
))}
|
|
186
|
-
</ul>
|
|
187
|
-
</div>
|
|
188
|
-
</div>
|
|
189
|
-
))}
|
|
190
|
-
|
|
191
|
-
<div className="col-span-3">
|
|
192
|
-
<div className="flex flex-col gap-4 animate-in fade-in slide-in-from-bottom-10 duration-1000 delay-100 ease-in-out fill-mode-both">
|
|
193
|
-
<p className="text-base font-medium text-foreground">
|
|
194
|
-
Contact Details
|
|
195
|
-
</p>
|
|
196
|
-
<ul className="flex flex-col gap-3">
|
|
197
|
-
<li>
|
|
198
|
-
<p className="text-base font-normal text-muted-foreground">
|
|
199
|
-
81 Rivington Street London EC2A 3AY
|
|
200
|
-
</p>
|
|
201
|
-
</li>
|
|
202
|
-
<li>
|
|
203
|
-
<a
|
|
204
|
-
href="mailto:contact@example.com"
|
|
205
|
-
className="text-base font-normal text-muted-foreground hover:text-foreground"
|
|
206
|
-
>
|
|
207
|
-
hello@shadcnspace.com
|
|
208
|
-
</a>
|
|
209
|
-
</li>
|
|
210
|
-
<li>
|
|
211
|
-
<a
|
|
212
|
-
href="tel:+01051923556"
|
|
213
|
-
className="text-base font-normal text-muted-foreground hover:text-foreground"
|
|
214
|
-
>
|
|
215
|
-
0105 192 3556
|
|
216
|
-
</a>
|
|
217
|
-
</li>
|
|
218
|
-
</ul>
|
|
219
|
-
</div>
|
|
220
|
-
</div>
|
|
221
|
-
</div>
|
|
222
|
-
<Separator orientation="horizontal" />
|
|
223
|
-
<p className="text-sm font-normal text-muted-foreground text-center animate-in fade-in slide-in-from-bottom-10 duration-1000 delay-100 ease-in-out fill-mode-both">
|
|
224
|
-
©2026 Shadcn Space. All Rights Reserved
|
|
225
|
-
</p>
|
|
226
|
-
</div>
|
|
227
|
-
</div>
|
|
228
|
-
</footer>
|
|
229
|
-
);
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
export default Footer;
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
-
// AllBlue - 理想之海
|
|
3
|
-
// Copyright (C) 2026 AllBlue Contributors
|
|
4
|
-
//
|
|
5
|
-
// This program is free software: you can redistribute it and/or modify
|
|
6
|
-
// it under the terms of the GNU Affero General Public License as published by
|
|
7
|
-
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
// (at your option) any later version.
|
|
9
|
-
//
|
|
10
|
-
// This program is distributed in the hope that it will be useful,
|
|
11
|
-
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
// GNU Affero General Public License for more details.
|
|
14
|
-
//
|
|
15
|
-
// You should have received a copy of the GNU Affero General Public License
|
|
16
|
-
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
-
|
|
18
|
-
import { Marquee } from "@/components/shadcn-space/animations/marquee";
|
|
19
|
-
import { m } from "motion/react";
|
|
20
|
-
|
|
21
|
-
export interface BrandList {
|
|
22
|
-
image: string;
|
|
23
|
-
name: string;
|
|
24
|
-
lightimg: string;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function BrandSlider({ brandList }: { brandList: BrandList[] }) {
|
|
28
|
-
return (
|
|
29
|
-
<section>
|
|
30
|
-
<div className="py-6 md:py-10">
|
|
31
|
-
<div className="mx-auto max-w-6xl">
|
|
32
|
-
<m.div
|
|
33
|
-
initial={{ opacity: 0, y: 32 }}
|
|
34
|
-
whileInView={{ opacity: 1, y: 0 }}
|
|
35
|
-
viewport={{ once: true }}
|
|
36
|
-
transition={{ duration: 1, delay: 0.6 }}
|
|
37
|
-
className="flex flex-col gap-3"
|
|
38
|
-
>
|
|
39
|
-
<div className="flex justify-center text-center py-3 md:py-4 relative">
|
|
40
|
-
<div className="flex items-center justify-center gap-4">
|
|
41
|
-
<div className="hidden md:block h-0.5 w-40 bg-linear-to-l from-muted-foreground to-white dark:from-muted-foreground dark:to-transparent opacity-20" />
|
|
42
|
-
<p className="text-sm font-normal sm:px-2 px-10 text-muted-foreground text-center">
|
|
43
|
-
Loved by 1000+ big and small brands around the worlds
|
|
44
|
-
</p>
|
|
45
|
-
<div className="hidden md:block h-0.5 w-40 bg-linear-to-r from-muted-foreground to-white dark:from-muted-foreground dark:to-transparent opacity-20" />
|
|
46
|
-
</div>
|
|
47
|
-
</div>
|
|
48
|
-
{brandList && brandList.length > 0 && (
|
|
49
|
-
<div className="py-4">
|
|
50
|
-
<Marquee pauseOnHover className="[--duration:20s] p-0">
|
|
51
|
-
{brandList.map((brand, index) => (
|
|
52
|
-
<div key={index}>
|
|
53
|
-
<img
|
|
54
|
-
src={brand.image}
|
|
55
|
-
alt={brand.name}
|
|
56
|
-
width={144}
|
|
57
|
-
height={32}
|
|
58
|
-
className="w-36 h-8 mr-6 lg:mr-20 dark:hidden"
|
|
59
|
-
/>
|
|
60
|
-
<img
|
|
61
|
-
src={brand.lightimg}
|
|
62
|
-
alt={brand.name}
|
|
63
|
-
width={144}
|
|
64
|
-
height={32}
|
|
65
|
-
className="hidden dark:block w-36 h-8 mr-12 lg:mr-20"
|
|
66
|
-
/>
|
|
67
|
-
</div>
|
|
68
|
-
))}
|
|
69
|
-
</Marquee>
|
|
70
|
-
</div>
|
|
71
|
-
)}
|
|
72
|
-
</m.div>
|
|
73
|
-
</div>
|
|
74
|
-
</div>
|
|
75
|
-
</section>
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export default BrandSlider;
|