-
Notifications
You must be signed in to change notification settings - Fork 138
[WIP] Dynamic island #2239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Dynamic island #2239
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| export interface AdvocacyMessage { | ||
| id: string; | ||
| title: string; | ||
| description: string; | ||
| socialProof: string; | ||
| imageUrl: string; | ||
| imageAlt: string; | ||
| overlayBadge: string; | ||
| link: string; | ||
| bgGradient?: string; | ||
| } | ||
|
|
||
| export const advocacyMessages: AdvocacyMessage[] = [ | ||
| { | ||
| id: "security-first", | ||
| title: "Zero Trust Network Security for Kubernetes", | ||
| description: "Implement zero-trust security principles with Calico's advanced network policies. Protect your workloads with micro-segmentation and threat detection that adapts to your environment.", | ||
| socialProof: "🔐 Securing 50M+ containers globally", | ||
| imageUrl: "https://www.tigera.io/app/uploads/2023/02/tutorial-observability-troubleshooting-532x200-1.png", | ||
| imageAlt: "Cybersecurity and network protection concept", | ||
| overlayBadge: "🛡️ Zero Trust", | ||
| link: "https://www.tigera.io/learn/guides/security/zero-trust/", | ||
| }, | ||
| { | ||
| id: "observability", | ||
| title: "Real-time Network Visibility & Monitoring with Calico Whisker", | ||
| description: "Gain complete visibility into your network traffic with Calico's advanced observability tools. Monitor, analyze, and troubleshoot network issues with powerful dashboards and alerts.", | ||
| socialProof: "📈 99.9% uptime guarantee", | ||
| imageUrl: "https://www.tigera.io/app/uploads/2025/05/tutorial-Kubernetes-with-Whisker-532x200-1.png", | ||
| imageAlt: "Data analytics and monitoring dashboard", | ||
| overlayBadge: "📊 Live Monitoring", | ||
| link: "https://www.tigera.io/tutorials/?_sf_s=Kubernetes%20Observability%20with%20Calico%20Whisker", | ||
| }, | ||
| { | ||
| id: "vmware-migration", | ||
| title: "VM migration using Kubevirt and Calico", | ||
| description: "Learn how to run virtual machines in a Kubernetes environment", | ||
| socialProof: "🎓 Interactive course in your browser!", | ||
| imageUrl: "https://www.tigera.io/app/uploads/2023/01/tutorial-VM-migration-Kubevirt-Calico-532x200-1.png", | ||
| imageAlt: "Team collaboration and support", | ||
| overlayBadge: "🎓 Free Course", | ||
| link: "https://www.tigera.io/tutorials/?_sf_s=VM%20migration%20using%20Kubevirt%20and%20Calico", | ||
| bgGradient: "linear(to-r, cyan.500, blue.500)" | ||
| } | ||
| ]; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| import * as React from 'react'; | ||
| import { Card, CardBody, Image, Text, Heading, Box, Flex } from "@chakra-ui/react" | ||
| import { advocacyMessages, AdvocacyMessage } from './advocacyMessages'; | ||
|
|
||
| interface ProductAdvocateProps { | ||
| messageId?: string; | ||
| } | ||
|
|
||
|
|
||
|
|
||
| const ProductAdvocate: React.FC<ProductAdvocateProps> = ({ messageId, ...rest }) => { | ||
|
|
||
| // Select message based on messageId or randomly if not provided | ||
| const [selectedMessage] = React.useState(() => { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You don't need to use state here. Just assign it to a variable Or better yet, use an object instead of an array You could create a type from your message ids and use that in your props for better typing |
||
| if (messageId) { | ||
| const targetedMessage = advocacyMessages.find(msg => msg.id === messageId); | ||
| if (targetedMessage) { | ||
| return targetedMessage; | ||
| } | ||
| // Fallback to random if messageId not found | ||
| console.warn(`Message with ID "${messageId}" not found, falling back to random selection`); | ||
| } | ||
|
|
||
| const randomIndex = Math.floor(Math.random() * advocacyMessages.length); | ||
| return advocacyMessages[randomIndex]; | ||
| }); | ||
|
|
||
| const handleCardClick = () => { | ||
| window.open(selectedMessage.link, '_blank'); | ||
| }; | ||
|
|
||
| // Default gradient fallback | ||
| const defaultGradient = "linear(to-r, blue.500, purple.600)"; | ||
|
|
||
| return ( | ||
| <Card | ||
| w="100%" | ||
| maxW="100%" | ||
| h={{ base: "auto", md: "150px" }} | ||
| maxH="150px" | ||
| overflow="hidden" | ||
| bgGradient={selectedMessage.bgGradient || defaultGradient} | ||
| color="white" | ||
| boxShadow="xl" | ||
| borderRadius="lg" | ||
| position="relative" | ||
| _hover={{ transform: 'translateY(-2px)', boxShadow: '2xl', cursor: 'pointer' }} | ||
| transition="all 0.3s ease" | ||
| onClick={handleCardClick} | ||
| > | ||
| <Flex direction={{ base: "column", md: "row" }} align="center" h="100%"> | ||
| <CardBody flex="1" p={{ base: 4, md: 6 }} h="100%" display="flex" flexDirection="column" justifyContent="center"> | ||
| <Flex direction="column" h="100%" justify="space-between"> | ||
| <Box> | ||
| <Heading _firstLetter={{ textTransform: "uppercase" }} | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because you're using a heading, this is showing in the TOC. Not sure if you meant that? @ctauchen
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you really need to use |
||
| size="md" | ||
| mb={2} | ||
| bgGradient="linear(to-r, yellow.200, orange.200)" | ||
| bgClip="text" | ||
| fontWeight="bold" | ||
| lineHeight="tight" | ||
| noOfLines={1} | ||
| > | ||
| {selectedMessage.title} | ||
| </Heading> | ||
|
|
||
| <Text fontSize="sm" mb={3} opacity={0.9} lineHeight="tight" noOfLines={2}> | ||
| {selectedMessage.description} | ||
| </Text> | ||
| </Box> | ||
|
|
||
| <Box> | ||
| <Text fontSize="xs" opacity={0.7} noOfLines={1}> | ||
| {selectedMessage.socialProof} | ||
| </Text> | ||
| </Box> | ||
| </Flex> | ||
| </CardBody> | ||
|
|
||
| <Box | ||
| flexShrink={0} | ||
| w={{ base: "100%", md: "200px" }} | ||
| h={{ base: "120px", md: "150px" }} | ||
| position="relative" | ||
| > | ||
| <Image | ||
| src={selectedMessage.imageUrl} | ||
| alt={selectedMessage.imageAlt} | ||
| w="100%" | ||
| h="100%" | ||
| objectFit="cover" | ||
| borderLeftRadius={{ base: "none", md: "lg" }} | ||
| borderTopRadius={{ base: "lg", md: "none" }} | ||
| /> | ||
| <Box | ||
| position="absolute" | ||
| top={2} | ||
| right={2} | ||
| bg="blackAlpha.700" | ||
| color="white" | ||
| px={2} | ||
| py={0.5} | ||
| borderRadius="sm" | ||
| fontSize="xs" | ||
| fontWeight="bold" | ||
| > | ||
| {selectedMessage.overlayBadge} | ||
| </Box> | ||
| </Box> | ||
| </Flex> | ||
| </Card> | ||
| ); | ||
| }; | ||
|
|
||
| export default ProductAdvocate; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| How advocate works? | ||
| === | ||
| pretty simple add the following import to the document header | ||
| ``` | ||
| import ProductAdvocate from '/src/___new___/components/ProductAdvocate'; | ||
| ``` | ||
|
|
||
| add the following code to where you want the advocate to appear | ||
| ``` | ||
| <ProductAdvocate /> | ||
| ``` | ||
|
|
||
| > note you can provide an id to get a specific message for a page. | ||
|
|
||
| for exmaple: | ||
|
Check failure on line 15 in src/___new___/components/ProductAdvocate/readme.md
|
||
| ``` | ||
| <ProductAdvocate messageId="ebpf" /> | ||
| ``` | ||
| this will link your advocate to the id in the `advocacyMessages.ts` file. | ||
|
|
||
| How can I change/add/delete a message? | ||
| === | ||
| navigate to advocacyMessages.ts and do your thing. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make sure you format this file