big card, elements list & page, navigation
This commit is contained in:
46
client/src/components/BigCard.astro
Normal file
46
client/src/components/BigCard.astro
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
---
|
||||||
|
// BigCard component - configurable card with link
|
||||||
|
interface Props {
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { url } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class="max-w-4xl mx-auto">
|
||||||
|
<a href={url} class="block group">
|
||||||
|
<div class="bg-gradient-to-br from-purple-600 to-pink-600 rounded-2xl shadow-2xl overflow-hidden transform transition-all duration-300 group-hover:scale-105 group-hover:shadow-3xl">
|
||||||
|
<div class="p-12 text-center text-white">
|
||||||
|
<!-- Icon -->
|
||||||
|
<div class="mb-6">
|
||||||
|
<svg class="w-24 h-24 mx-auto text-white/90" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Title -->
|
||||||
|
<h2 class="text-4xl font-bold mb-4 group-hover:text-white transition-colors">
|
||||||
|
Pole Elements
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<!-- Description -->
|
||||||
|
<p class="text-xl text-white/90 mb-8 max-w-2xl mx-auto leading-relaxed">
|
||||||
|
Explore a comprehensive collection of pole dance elements, techniques, and combinations.
|
||||||
|
From basic spins to advanced tricks, discover everything you need to master pole sport.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<!-- CTA Button -->
|
||||||
|
<div class="inline-flex items-center space-x-2 bg-white/20 backdrop-blur-sm rounded-full px-8 py-4 group-hover:bg-white/30 transition-all duration-300">
|
||||||
|
<span class="text-lg font-semibold">Explore Elements</span>
|
||||||
|
<svg class="w-5 h-5 transform group-hover:translate-x-1 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Decorative elements -->
|
||||||
|
<div class="absolute top-4 right-4 w-16 h-16 bg-white/10 rounded-full"></div>
|
||||||
|
<div class="absolute bottom-8 left-8 w-8 h-8 bg-white/10 rounded-full"></div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
46
client/src/components/ElementsCard.astro
Normal file
46
client/src/components/ElementsCard.astro
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
---
|
||||||
|
// BigCard component - configurable card with link
|
||||||
|
interface Props {
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { url } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class="max-w-4xl mx-auto">
|
||||||
|
<a href={url} class="block group">
|
||||||
|
<div class="bg-gradient-to-br from-purple-600 to-pink-600 rounded-2xl shadow-2xl overflow-hidden transform transition-all duration-300 group-hover:scale-105 group-hover:shadow-3xl">
|
||||||
|
<div class="p-12 text-center text-white">
|
||||||
|
<!-- Icon -->
|
||||||
|
<div class="mb-6">
|
||||||
|
<svg class="w-24 h-24 mx-auto text-white/90" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Title -->
|
||||||
|
<h2 class="text-4xl font-bold mb-4 group-hover:text-white transition-colors">
|
||||||
|
Pole Elements
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<!-- Description -->
|
||||||
|
<p class="text-xl text-white/90 mb-8 max-w-2xl mx-auto leading-relaxed">
|
||||||
|
Explore a comprehensive collection of pole dance elements, techniques, and combinations.
|
||||||
|
From basic spins to advanced tricks, discover everything you need to master pole sport.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<!-- CTA Button -->
|
||||||
|
<div class="inline-flex items-center space-x-2 bg-white/20 backdrop-blur-sm rounded-full px-8 py-4 group-hover:bg-white/30 transition-all duration-300">
|
||||||
|
<span class="text-lg font-semibold">Explore Elements</span>
|
||||||
|
<svg class="w-5 h-5 transform group-hover:translate-x-1 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Decorative elements -->
|
||||||
|
<div class="absolute top-4 right-4 w-16 h-16 bg-white/10 rounded-full"></div>
|
||||||
|
<div class="absolute bottom-8 left-8 w-8 h-8 bg-white/10 rounded-full"></div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
77
client/src/components/Navigation.astro
Normal file
77
client/src/components/Navigation.astro
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
---
|
||||||
|
// Navigation component for Pole Sport website
|
||||||
|
---
|
||||||
|
|
||||||
|
<nav class="bg-white shadow-lg">
|
||||||
|
<div class="container mx-auto px-4">
|
||||||
|
<div class="flex justify-between items-center py-4">
|
||||||
|
<!-- Logo/Brand -->
|
||||||
|
<div class="flex items-center">
|
||||||
|
<a href="/" class="text-xl font-bold text-gray-800 hover:text-gray-600 transition-colors">
|
||||||
|
Pole Sport
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Navigation Links -->
|
||||||
|
<div class="hidden md:flex space-x-8">
|
||||||
|
<a href="/" class="text-gray-600 hover:text-gray-900 transition-colors font-medium">
|
||||||
|
Home
|
||||||
|
</a>
|
||||||
|
<a href="/elements" class="text-gray-600 hover:text-gray-900 transition-colors font-medium">
|
||||||
|
Elements
|
||||||
|
</a>
|
||||||
|
<a href="/techniques" class="text-gray-600 hover:text-gray-900 transition-colors font-medium">
|
||||||
|
Techniques
|
||||||
|
</a>
|
||||||
|
<a href="/training" class="text-gray-600 hover:text-gray-900 transition-colors font-medium">
|
||||||
|
Training
|
||||||
|
</a>
|
||||||
|
<a href="/about" class="text-gray-600 hover:text-gray-900 transition-colors font-medium">
|
||||||
|
About
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Mobile menu button -->
|
||||||
|
<div class="md:hidden">
|
||||||
|
<button id="mobile-menu-button" class="text-gray-600 hover:text-gray-900 focus:outline-none">
|
||||||
|
<svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Mobile menu -->
|
||||||
|
<div id="mobile-menu" class="md:hidden hidden">
|
||||||
|
<div class="px-2 pt-2 pb-3 space-y-1 sm:px-3">
|
||||||
|
<a href="/" class="block px-3 py-2 text-gray-600 hover:text-gray-900 hover:bg-gray-50 rounded-md font-medium">
|
||||||
|
Home
|
||||||
|
</a>
|
||||||
|
<a href="/elements" class="block px-3 py-2 text-gray-600 hover:text-gray-900 hover:bg-gray-50 rounded-md font-medium">
|
||||||
|
Elements
|
||||||
|
</a>
|
||||||
|
<a href="/techniques" class="block px-3 py-2 text-gray-600 hover:text-gray-900 hover:bg-gray-50 rounded-md font-medium">
|
||||||
|
Techniques
|
||||||
|
</a>
|
||||||
|
<a href="/training" class="block px-3 py-2 text-gray-600 hover:text-gray-900 hover:bg-gray-50 rounded-md font-medium">
|
||||||
|
Training
|
||||||
|
</a>
|
||||||
|
<a href="/about" class="block px-3 py-2 text-gray-600 hover:text-gray-900 hover:bg-gray-50 rounded-md font-medium">
|
||||||
|
About
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Mobile menu toggle functionality
|
||||||
|
const mobileMenuButton = document.getElementById('mobile-menu-button');
|
||||||
|
const mobileMenu = document.getElementById('mobile-menu');
|
||||||
|
|
||||||
|
if (mobileMenuButton && mobileMenu) {
|
||||||
|
mobileMenuButton.addEventListener('click', () => {
|
||||||
|
mobileMenu.classList.toggle('hidden');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -22,10 +22,12 @@ const strapiPoleElementsLoader = defineCollection({
|
|||||||
// Fetch articles from Strapi
|
// Fetch articles from Strapi
|
||||||
const poleElementsData = await fetch(url.href);
|
const poleElementsData = await fetch(url.href);
|
||||||
const { data }= await poleElementsData.json();
|
const { data }= await poleElementsData.json();
|
||||||
|
|
||||||
// Transform the API response into the desired data structure
|
// Transform the API response into the desired data structure
|
||||||
return data.map((item) => ({
|
return data.map((item) => ({
|
||||||
id: item.id.toString(),
|
id: item.id.toString(),
|
||||||
name: item.name,
|
name: item.name,
|
||||||
|
title: item.name,
|
||||||
description: item.description,
|
description: item.description,
|
||||||
createdAt: item.createdAt,
|
createdAt: item.createdAt,
|
||||||
updatedAt: item.updatedAt,
|
updatedAt: item.updatedAt,
|
||||||
@@ -42,6 +44,7 @@ const strapiPoleElementsLoader = defineCollection({
|
|||||||
schema: z.object({
|
schema: z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
name: z.string(),
|
name: z.string(),
|
||||||
|
title: z.string(),
|
||||||
description: z.string(),
|
description: z.string(),
|
||||||
createdAt: z.string(),
|
createdAt: z.string(),
|
||||||
updatedAt: z.string(),
|
updatedAt: z.string(),
|
||||||
|
|||||||
12
client/src/layouts/Head.astro
Normal file
12
client/src/layouts/Head.astro
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
const { title, description } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<meta name="generator" content={ Astro.generator} />
|
||||||
|
<meta name="description" content={description} />
|
||||||
|
<title>{title}</title>
|
||||||
|
</head>
|
||||||
@@ -1,16 +1,14 @@
|
|||||||
---
|
---
|
||||||
import "../styles/global.css";
|
import "../styles/global.css";
|
||||||
|
import Head from "./Head.astro";
|
||||||
|
import Navigation from "../components/Navigation.astro";
|
||||||
|
const { title = "Just a title", description = "Adescription" } = Astro.props;
|
||||||
---
|
---
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<Head {title} {description} />
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width" />
|
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
||||||
<meta name="generator" content={Astro.generator} />
|
|
||||||
<title>Astro Basics</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
|
<Navigation />
|
||||||
<slot />
|
<slot />
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
28
client/src/pages/elements.astro
Normal file
28
client/src/pages/elements.astro
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
// Import necessary components and utilities
|
||||||
|
import Layout from "../layouts/Layout.astro";
|
||||||
|
import { getCollection } from "astro:content";
|
||||||
|
import PoleElementsList from "../components/PoleElementsList.astro";
|
||||||
|
import { getStrapiBaseUrl } from "../config/strapi";
|
||||||
|
|
||||||
|
// Fetch all posts from Strapi using Astro's content collection
|
||||||
|
const strapiPoleElements = await getCollection("strapiPoleElementsLoader");
|
||||||
|
// Get Strapi URL from global config
|
||||||
|
const BASE_URL = getStrapiBaseUrl();
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title="Pole Elements" description="Pole Elements">
|
||||||
|
<div class="container mx-auto p-4">
|
||||||
|
<!-- Main heading -->
|
||||||
|
<h1 class="text-3xl font-bold mb-8">
|
||||||
|
Pole Elements
|
||||||
|
</h1>
|
||||||
|
<!-- Pole Elements List -->
|
||||||
|
<PoleElementsList
|
||||||
|
elements={strapiPoleElements}
|
||||||
|
class="max-w-4xl mx-auto space-y-4"
|
||||||
|
id="pole-elements-list"
|
||||||
|
data-testid="pole-elements"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Layout>
|
||||||
@@ -1,28 +1,13 @@
|
|||||||
---
|
---
|
||||||
// Import necessary components and utilities
|
// Import necessary components and utilities
|
||||||
import Layout from "../layouts/Layout.astro";
|
import Layout from "../layouts/Layout.astro";
|
||||||
import { getCollection } from "astro:content";
|
import ElementsCard from "../components/ElementsCard.astro";
|
||||||
import PoleElementsList from "../components/PoleElementsList.astro";
|
|
||||||
import { getStrapiBaseUrl } from "../config/strapi";
|
|
||||||
|
|
||||||
// Fetch all posts from Strapi using Astro's content collection
|
|
||||||
const strapiPoleElements = await getCollection("strapiPoleElementsLoader");
|
|
||||||
// Get Strapi URL from global config
|
|
||||||
const BASE_URL = getStrapiBaseUrl();
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout>
|
<Layout title="Pole Elements" description="Pole Elements">
|
||||||
<div class="container mx-auto p-4">
|
<div class="container mx-auto p-4">
|
||||||
<!-- Main heading -->
|
<div class="py-12">
|
||||||
<h1 class="text-3xl font-bold mb-8">
|
<ElementsCard url="/elements" />
|
||||||
Hello Strapi 5 and Astro 5 World
|
</div>
|
||||||
</h1>
|
|
||||||
<!-- Pole Elements List -->
|
|
||||||
<PoleElementsList
|
|
||||||
elements={strapiPoleElements}
|
|
||||||
class="max-w-4xl mx-auto space-y-4"
|
|
||||||
id="pole-elements-list"
|
|
||||||
data-testid="pole-elements"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|||||||
Reference in New Issue
Block a user