From 5ae8ee03f97a8959b9c8be70d8bd12b0c9c5c83e Mon Sep 17 00:00:00 2001 From: neroices Date: Sat, 21 Dec 2024 07:03:59 +0700 Subject: [PATCH] www: Add metadata Change-Id: I5bb58c5aba1a5947d5a660f56cce680a5fadd683 --- src/app/about/page.tsx | 119 ++-------------- src/app/devices/page.tsx | 244 +------------------------------- src/app/layout.tsx | 10 ++ src/app/page.tsx | 162 +-------------------- src/components/about-page.tsx | 114 +++++++++++++++ src/components/devices-page.tsx | 242 +++++++++++++++++++++++++++++++ src/components/homepage.tsx | 160 +++++++++++++++++++++ 7 files changed, 546 insertions(+), 505 deletions(-) create mode 100644 src/components/about-page.tsx create mode 100644 src/components/devices-page.tsx create mode 100644 src/components/homepage.tsx diff --git a/src/app/about/page.tsx b/src/app/about/page.tsx index 242e5a8..8788c7e 100644 --- a/src/app/about/page.tsx +++ b/src/app/about/page.tsx @@ -1,114 +1,11 @@ -"use client"; +import AboutPage from '@/components/about-page' -import { motion } from "framer-motion"; -import { TeamMember } from "@/components/team-member"; - -const teamMembers = [ - { - name: "Toufu", - role: "Founder/Lead Developer", - image: "/toufu.png", - github: "toufune", - }, - { - name: "Maitani-Sakura", - role: "Co-Founder/Developer", - image: "/maitani-sakura.png", - github: "maitani-sakura", - }, - { - name: "soralis0912", - role: "Developer", - image: "/soralis0912.png", - github: "soralis0912", - }, - { - name: "neroices", - role: "Developer", - image: "/neroices.png", - github: "neroices", - }, - { - name: "MONE-FIERA", - role: "Developer", - image: "/monefiera.png", - github: "monefiera", - }, - { - name: "Yumagi", - role: "Developer", - image: "/yumagi.png", - github: "ymag-h", - }, - { - name: "satokun2668", - role: "Designer", - image: "/satokun.jpg", - github: "numaaqours", - }, - { - name: "Garry050", - role: "Advisor", - image: "/garry050.png", - github: "garry050", - }, -]; - -const fadeInUp = { - initial: { opacity: 0, y: 20 }, - animate: { opacity: 1, y: 0 }, - transition: { duration: 0.5 }, -}; +export const metadata = { + title: 'About', + description: 'About WitAqua.', +} -export default function AboutPage() { - return ( - - - About WitAqua - - -

- { - "We're a small team of passionate Android enthusiasts from Japan, and we've come together to create something special. It all started because we love the simplicity of stock Android but felt it could use a little more personality and practicality without all the unnecessary bloat. So, we rolled up our sleeves and got to work, crafting a clean, and responsive." - } -

-

- { - "We kept the core Android experience intact while adding some carefully chosen enhancements to make your device more customizable, and just plain better to use. We're not a big corporation or a fancy tech giant. We're just a group of like-minded developers who love tinkering with Android and making it better for everyone." - } -

-

- { - "So, whether you're here to try something new, or just curious about what we're building, welcome to WitAqua! We're excited to have you join us on this journey at a time." - } -

-
- -

Our Team

-
- {teamMembers.map((member, index) => ( - - - - ))} -
-
-
- ); +export default function About() { + return } + diff --git a/src/app/devices/page.tsx b/src/app/devices/page.tsx index 0a76557..5facf1c 100644 --- a/src/app/devices/page.tsx +++ b/src/app/devices/page.tsx @@ -1,242 +1,10 @@ -"use client"; +import DevicesPage from '@/components/devices-page' -import { useState, useEffect } from "react"; -import { Download, Github, Search, AlertTriangle } from "lucide-react"; -import { Input } from "@/components/ui/input"; -import { Button } from "@/components/ui/button"; -import { - Accordion, - AccordionContent, - AccordionItem, - AccordionTrigger, -} from "@/components/ui/accordion"; -import { - Dialog, - DialogContent, - DialogHeader, - DialogTitle, - DialogDescription, - DialogTrigger, -} from "@/components/ui/dialog"; -import type { Device } from "@/types/device"; - -export default function DevicesPage() { - const [devices, setDevices] = useState([]); - const [searchQuery, setSearchQuery] = useState(""); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - - useEffect(() => { - const fetchDevicesData = async () => { - try { - const response = await fetch( - "https://raw.githubusercontent.com/WitAqua/WitAquaOTA/refs/heads/main/data/devices.json", - ); - if (!response.ok) { - throw new Error( - `Failed to fetch devices data. Status: ${response.status}`, - ); - } - const data = await response.json(); - setDevices(data.devices); // Assuming the JSON contains an array of devices under 'devices' - } catch (e) { - console.error("Error loading devices:", e); - setError("Failed to load devices data"); - } finally { - setLoading(false); - } - }; - - fetchDevicesData(); - }, []); - - const filteredDevices = devices.filter( - (device) => - device.name.toLowerCase().includes(searchQuery.toLowerCase()) || - device.codename.toLowerCase().includes(searchQuery.toLowerCase()) || - device.brand.toLowerCase().includes(searchQuery.toLowerCase()), - ); - - const { deprecatedDevices, activeDevices } = filteredDevices.reduce( - (acc, device) => { - if (device.deprecated) { - acc.deprecatedDevices.push(device); - } else { - if (!acc.activeDevices[device.brand]) { - acc.activeDevices[device.brand] = []; - } - acc.activeDevices[device.brand].push(device); - } - return acc; - }, - { deprecatedDevices: [], activeDevices: {} } as { - deprecatedDevices: Device[]; - activeDevices: Record; - }, - ); - - return ( -
-
-
- - setSearchQuery(e.target.value)} - /> -
- - {loading ? ( -
Loading devices...
- ) : error ? ( -
- Error: {error}. Please try again later or contact support. -
- ) : ( - - {Object.entries(activeDevices).map(([brand, devices]) => ( - - {brand} - -
- {devices.map((device) => ( - - ))} -
-
-
- ))} - {deprecatedDevices.length > 0 && ( - - - Deprecated Devices - - -
- {deprecatedDevices.map((device) => ( - - ))} -
-
-
- )} -
- )} -
-
- ); +export const metadata = { + title: 'Supported Devices', } -function DeviceItem({ device }: { device: Device }) { - const [changelog, setChangelog] = useState(""); - - const handleFetchChangelog = async () => { - try { - const response = await fetch( - `https://raw.githubusercontent.com/WitAqua/WitAquaOTA/refs/heads/main/changelog/${device.codename}`, - ); - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - const text = await response.text(); - setChangelog(text); - } catch (error) { - console.error("Error fetching changelog:", error); - setChangelog( - `Failed to load changelog for ${device.name} (${device.codename}). Please try again later.`, - ); - } - }; - - return ( -
-
-
- {device.name} - {device.deprecated && ( - - )} -
- {device.codename} - - Android {device.latestAndroidVersion} | Latest build:{" "} - {device.latestBuildDate} - -
- - Maintainer: {device.maintainer.name} - - {device.maintainer.github && ( - - - - )} -
-
-
- - - - - - - Changelog for {device.name} - -
-
-                    {changelog}
-                  
-
-
-
-
-
- - - - - - {device.installUrl && ( - - )} -
-
- ); +export default function Devices() { + return } + diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 1957445..a194c01 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -2,11 +2,21 @@ import { Inter } from "next/font/google"; import { ThemeProvider } from "./providers"; import { SiteHeader } from "@/components/site-header"; import { SiteFooter } from "@/components/site-footer"; +import { Metadata } from "next"; import "./globals.css"; const inter = Inter({ subsets: ["latin"] }); +export const metadata: Metadata = { + title: { + default: 'WitAqua', + template: '%s | WitAqua' + }, + description: 'A custom Android ROM developed by Japanese Android enthusiasts.', +} + + export default function RootLayout({ children, }: { diff --git a/src/app/page.tsx b/src/app/page.tsx index 6f73760..5a0f0be 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,160 +1,10 @@ -"use client"; +import HomePage from '@/components/homepage' -import Image from "next/image"; -import Link from "next/link"; -import { motion } from "framer-motion"; -import { - ArrowRight, - PaintbrushVertical, - CircleFadingArrowUp, - Smartphone, -} from "lucide-react"; -import { Button } from "@/components/ui/button"; - -const MotionImage = motion.create(Image); - -const fadeIn = { - initial: { opacity: 0, y: 20 }, - animate: { opacity: 1, y: 0 }, - transition: { duration: 0.5 }, -}; - -const features = [ - { - icon: PaintbrushVertical, - title: "Customizable Features", - description: - "Add some extra functionality with a few thoughtful, carefully selected features that enhance usability and personalization without compromising system performance.", - }, - { - icon: CircleFadingArrowUp, - title: "Frequent Stable Updates", - description: - "These updates are carefully tested and designed to keep your system in a stable state while ensuring you always have the latest security patches and improvements.", - }, - { - icon: Smartphone, - title: "Stock Android Experience", - description: - "Enjoy a clean, bloat-free interface that stays true to the pure Android design and functionality.", - }, -]; +export const metadata = { + title: 'Home', +} export default function Home() { - return ( -
-
-
- - - - WitAqua - - - WitAqua is a custom Android ROM developed by Japanese Android - enthusiasts. The primary goal of this ROM is to deliver a stock - Android experience, free from unnecessary bloatware. It offers a - clean, responsive system with a streamlined interface. While the - ROM maintains the core features and simplicity of stock Android, - it also includes several useful, carefully selected enhancements - and additional features that improve usability and customization. - - - - - - - - - - -
- -
-
- - Features - -
- {features.map((feature, index) => ( - - -

- {feature.title} -

-

{feature.description}

-
- ))} -
-
-
- -
-
- -
-

Contributing

-

- { - "Interested in contributing? We welcome contributions from developers and enthusiasts around the globe. Whether it's fixing bugs, adding features, or improving documentation, your help is invaluable." - } -

-

- {"To get started, visit our GitHub repository."} -

- - - -
-
-
-
-
-
- ); + return } + diff --git a/src/components/about-page.tsx b/src/components/about-page.tsx new file mode 100644 index 0000000..242e5a8 --- /dev/null +++ b/src/components/about-page.tsx @@ -0,0 +1,114 @@ +"use client"; + +import { motion } from "framer-motion"; +import { TeamMember } from "@/components/team-member"; + +const teamMembers = [ + { + name: "Toufu", + role: "Founder/Lead Developer", + image: "/toufu.png", + github: "toufune", + }, + { + name: "Maitani-Sakura", + role: "Co-Founder/Developer", + image: "/maitani-sakura.png", + github: "maitani-sakura", + }, + { + name: "soralis0912", + role: "Developer", + image: "/soralis0912.png", + github: "soralis0912", + }, + { + name: "neroices", + role: "Developer", + image: "/neroices.png", + github: "neroices", + }, + { + name: "MONE-FIERA", + role: "Developer", + image: "/monefiera.png", + github: "monefiera", + }, + { + name: "Yumagi", + role: "Developer", + image: "/yumagi.png", + github: "ymag-h", + }, + { + name: "satokun2668", + role: "Designer", + image: "/satokun.jpg", + github: "numaaqours", + }, + { + name: "Garry050", + role: "Advisor", + image: "/garry050.png", + github: "garry050", + }, +]; + +const fadeInUp = { + initial: { opacity: 0, y: 20 }, + animate: { opacity: 1, y: 0 }, + transition: { duration: 0.5 }, +}; + +export default function AboutPage() { + return ( + + + About WitAqua + + +

+ { + "We're a small team of passionate Android enthusiasts from Japan, and we've come together to create something special. It all started because we love the simplicity of stock Android but felt it could use a little more personality and practicality without all the unnecessary bloat. So, we rolled up our sleeves and got to work, crafting a clean, and responsive." + } +

+

+ { + "We kept the core Android experience intact while adding some carefully chosen enhancements to make your device more customizable, and just plain better to use. We're not a big corporation or a fancy tech giant. We're just a group of like-minded developers who love tinkering with Android and making it better for everyone." + } +

+

+ { + "So, whether you're here to try something new, or just curious about what we're building, welcome to WitAqua! We're excited to have you join us on this journey at a time." + } +

+
+ +

Our Team

+
+ {teamMembers.map((member, index) => ( + + + + ))} +
+
+
+ ); +} diff --git a/src/components/devices-page.tsx b/src/components/devices-page.tsx new file mode 100644 index 0000000..0a76557 --- /dev/null +++ b/src/components/devices-page.tsx @@ -0,0 +1,242 @@ +"use client"; + +import { useState, useEffect } from "react"; +import { Download, Github, Search, AlertTriangle } from "lucide-react"; +import { Input } from "@/components/ui/input"; +import { Button } from "@/components/ui/button"; +import { + Accordion, + AccordionContent, + AccordionItem, + AccordionTrigger, +} from "@/components/ui/accordion"; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogDescription, + DialogTrigger, +} from "@/components/ui/dialog"; +import type { Device } from "@/types/device"; + +export default function DevicesPage() { + const [devices, setDevices] = useState([]); + const [searchQuery, setSearchQuery] = useState(""); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + const fetchDevicesData = async () => { + try { + const response = await fetch( + "https://raw.githubusercontent.com/WitAqua/WitAquaOTA/refs/heads/main/data/devices.json", + ); + if (!response.ok) { + throw new Error( + `Failed to fetch devices data. Status: ${response.status}`, + ); + } + const data = await response.json(); + setDevices(data.devices); // Assuming the JSON contains an array of devices under 'devices' + } catch (e) { + console.error("Error loading devices:", e); + setError("Failed to load devices data"); + } finally { + setLoading(false); + } + }; + + fetchDevicesData(); + }, []); + + const filteredDevices = devices.filter( + (device) => + device.name.toLowerCase().includes(searchQuery.toLowerCase()) || + device.codename.toLowerCase().includes(searchQuery.toLowerCase()) || + device.brand.toLowerCase().includes(searchQuery.toLowerCase()), + ); + + const { deprecatedDevices, activeDevices } = filteredDevices.reduce( + (acc, device) => { + if (device.deprecated) { + acc.deprecatedDevices.push(device); + } else { + if (!acc.activeDevices[device.brand]) { + acc.activeDevices[device.brand] = []; + } + acc.activeDevices[device.brand].push(device); + } + return acc; + }, + { deprecatedDevices: [], activeDevices: {} } as { + deprecatedDevices: Device[]; + activeDevices: Record; + }, + ); + + return ( +
+
+
+ + setSearchQuery(e.target.value)} + /> +
+ + {loading ? ( +
Loading devices...
+ ) : error ? ( +
+ Error: {error}. Please try again later or contact support. +
+ ) : ( + + {Object.entries(activeDevices).map(([brand, devices]) => ( + + {brand} + +
+ {devices.map((device) => ( + + ))} +
+
+
+ ))} + {deprecatedDevices.length > 0 && ( + + + Deprecated Devices + + +
+ {deprecatedDevices.map((device) => ( + + ))} +
+
+
+ )} +
+ )} +
+
+ ); +} + +function DeviceItem({ device }: { device: Device }) { + const [changelog, setChangelog] = useState(""); + + const handleFetchChangelog = async () => { + try { + const response = await fetch( + `https://raw.githubusercontent.com/WitAqua/WitAquaOTA/refs/heads/main/changelog/${device.codename}`, + ); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + const text = await response.text(); + setChangelog(text); + } catch (error) { + console.error("Error fetching changelog:", error); + setChangelog( + `Failed to load changelog for ${device.name} (${device.codename}). Please try again later.`, + ); + } + }; + + return ( +
+
+
+ {device.name} + {device.deprecated && ( + + )} +
+ {device.codename} + + Android {device.latestAndroidVersion} | Latest build:{" "} + {device.latestBuildDate} + +
+ + Maintainer: {device.maintainer.name} + + {device.maintainer.github && ( + + + + )} +
+
+
+ + + + + + + Changelog for {device.name} + +
+
+                    {changelog}
+                  
+
+
+
+
+
+ + + + + + {device.installUrl && ( + + )} +
+
+ ); +} diff --git a/src/components/homepage.tsx b/src/components/homepage.tsx new file mode 100644 index 0000000..6f73760 --- /dev/null +++ b/src/components/homepage.tsx @@ -0,0 +1,160 @@ +"use client"; + +import Image from "next/image"; +import Link from "next/link"; +import { motion } from "framer-motion"; +import { + ArrowRight, + PaintbrushVertical, + CircleFadingArrowUp, + Smartphone, +} from "lucide-react"; +import { Button } from "@/components/ui/button"; + +const MotionImage = motion.create(Image); + +const fadeIn = { + initial: { opacity: 0, y: 20 }, + animate: { opacity: 1, y: 0 }, + transition: { duration: 0.5 }, +}; + +const features = [ + { + icon: PaintbrushVertical, + title: "Customizable Features", + description: + "Add some extra functionality with a few thoughtful, carefully selected features that enhance usability and personalization without compromising system performance.", + }, + { + icon: CircleFadingArrowUp, + title: "Frequent Stable Updates", + description: + "These updates are carefully tested and designed to keep your system in a stable state while ensuring you always have the latest security patches and improvements.", + }, + { + icon: Smartphone, + title: "Stock Android Experience", + description: + "Enjoy a clean, bloat-free interface that stays true to the pure Android design and functionality.", + }, +]; + +export default function Home() { + return ( +
+
+
+ + + + WitAqua + + + WitAqua is a custom Android ROM developed by Japanese Android + enthusiasts. The primary goal of this ROM is to deliver a stock + Android experience, free from unnecessary bloatware. It offers a + clean, responsive system with a streamlined interface. While the + ROM maintains the core features and simplicity of stock Android, + it also includes several useful, carefully selected enhancements + and additional features that improve usability and customization. + + + + + + + + + + +
+ +
+
+ + Features + +
+ {features.map((feature, index) => ( + + +

+ {feature.title} +

+

{feature.description}

+
+ ))} +
+
+
+ +
+
+ +
+

Contributing

+

+ { + "Interested in contributing? We welcome contributions from developers and enthusiasts around the globe. Whether it's fixing bugs, adding features, or improving documentation, your help is invaluable." + } +

+

+ {"To get started, visit our GitHub repository."} +

+ + + +
+
+
+
+
+
+ ); +}