Compare commits
39 Commits
kx3dex_rad
...
master
Author | SHA1 | Date |
---|---|---|
Robert Burgess | ff979a2cfc | |
Dex | d6958ea3ea | |
Dex | 221d7f9c72 | |
Dex | 84b0d5923d | |
Dex | 6e12955241 | |
Dex | 571d5558b1 | |
Dex | 38ad6bbe53 | |
Dex | fe7bbf995f | |
Dex | d44acad05c | |
Dex | 6b0be661bd | |
Dex | 21ae7fa91c | |
Dex | 03d159e358 | |
Dex | d2262d7f2d | |
Dex | 874fd6d9c3 | |
Dex | ae27af92a7 | |
Dex | 9bf6a0e4b5 | |
Dex | 1af01fa8a7 | |
Dex | e0ed17bd66 | |
Dex | 9e81d7be45 | |
Dex Burgess | d675ceb261 | |
Dex | 8dfe805cef | |
Dex | 076025f977 | |
Dex | 325d736536 | |
Dex | bf32f4a33a | |
Dex Burgess | f18cee6775 | |
Dex Burgess | 7ad8713fb9 | |
Dex | 6dcae4ffa8 | |
Dex | dc90d2ac4d | |
Dex | 2d81c10377 | |
Dex | d3b581574a | |
Dex | bbf7753ad0 | |
Dex | 889a70fe65 | |
Dex | 5bca013e5a | |
Dex | 065b364390 | |
Dex | d4215470c1 | |
Dex | 4f39a6169c | |
Dex | ec8649d0c6 | |
Dex | 6711b3f240 | |
Dex | 1d54c34812 |
|
@ -13,20 +13,39 @@ jobs:
|
||||||
- name: Check out repository code
|
- name: Check out repository code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: actions/github-script@v7
|
||||||
|
id: set-result
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
var fs = require("fs")
|
||||||
|
var content = fs.readFileSync("package.json", { encoding: 'utf8', flag: 'r' })
|
||||||
|
var pkg = JSON.parse(content)
|
||||||
|
return pkg.version
|
||||||
|
result-encoding: string
|
||||||
|
|
||||||
|
- name: Get result
|
||||||
|
run: echo "gitea.simplysyncedllc.com/dex/kx3dex_radio:${{steps.set-result.outputs.result}}"
|
||||||
|
|
||||||
|
- name: Install QEMU
|
||||||
|
run: apt-get update && apt-get install -y qemu-user-static
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: '18.20.0'
|
node-version: '18.20.0'
|
||||||
|
|
||||||
- name: Create a new release and publish package.
|
- name: Create a new release and publish package.
|
||||||
|
id: release
|
||||||
run: |
|
run: |
|
||||||
CURR_VER="$(cat package.json | jq -r .name)_v$(cat package.json | jq -r .version)"
|
CURR_VER="$(cat package.json | jq -r .name)_v$(cat package.json | jq -r .version)"
|
||||||
CURR_NAME="$(cat package.json | jq -r .name) v$(cat package.json | jq -r .version)"
|
CURR_NAME="$(cat package.json | jq -r .name) v$(cat package.json | jq -r .version)"
|
||||||
|
|
||||||
echo "Checking https://gitea.simplysyncedllc.com/api/v1/repos/${{ gitea.repository }}/releases for name ${CURR_NAME}"
|
echo "Checking https://gitea.simplysyncedllc.com/api/v1/repos/${{ gitea.repository }}/releases for name ${CURR_NAME}"
|
||||||
|
|
||||||
if curl -s -X GET -H "Authorization: token ${{ secrets.action_token }}" https://gitea.simplysyncedllc.com/api/v1/repos/${{ gitea.repository }}/releases | grep -o "\"name\"\:\"${CURR_NAME}\"" > /dev/null; then
|
if curl -s -X GET -H "Authorization: token ${{ secrets.ACTION_TOKEN }}" https://gitea.simplysyncedllc.com/api/v1/repos/${{ gitea.repository }}/releases | grep -o "\"name\"\:\"${CURR_NAME}\"" > /dev/null; then
|
||||||
|
|
||||||
echo "Skipping ${{ gitea.job }} since $CURR_NAME already exists";
|
echo "Skipping ${{ gitea.job }} since $CURR_NAME already exists";
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
@ -38,7 +57,7 @@ jobs:
|
||||||
echo "Creating ${CURR_VER} release on gitea"
|
echo "Creating ${CURR_VER} release on gitea"
|
||||||
RELEASE_RESULT=$(curl \
|
RELEASE_RESULT=$(curl \
|
||||||
-X POST \
|
-X POST \
|
||||||
-H "Authorization: token ${{ secrets.action_token }}" \
|
-H "Authorization: token ${{ secrets.ACTION_TOKEN }}" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
https://gitea.simplysyncedllc.com/api/v1/repos/${{ gitea.repository }}/releases \
|
https://gitea.simplysyncedllc.com/api/v1/repos/${{ gitea.repository }}/releases \
|
||||||
-d "{\"tag_name\":\"${CURR_VER}\",\"name\":\"${CURR_NAME}\",\"body\":\"Automatic release from gitea :\n\n${{ gitea.event.head_commit.message }}\"}")
|
-d "{\"tag_name\":\"${CURR_VER}\",\"name\":\"${CURR_NAME}\",\"body\":\"Automatic release from gitea :\n\n${{ gitea.event.head_commit.message }}\"}")
|
||||||
|
@ -49,24 +68,18 @@ jobs:
|
||||||
|
|
||||||
curl \
|
curl \
|
||||||
-X POST \
|
-X POST \
|
||||||
-H "Authorization: token ${{ secrets.action_token }}" \
|
-H "Authorization: token ${{ secrets.ACTION_TOKEN }}" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
https://gitea.simplysyncedllc.com/api/v1/repos/${{ gitea.repository }}/releases/$RELEASE_ID/assets
|
https://gitea.simplysyncedllc.com/api/v1/repos/${{ gitea.repository }}/releases/$RELEASE_ID/assets
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
- name: Build Docker container and put in gitea registry.
|
uses: docker/build-push-action@v5
|
||||||
run: |
|
|
||||||
echo "${{ secrets.action_token }}" | docker login gitea.dex -u dex --password-stdin
|
|
||||||
docker build -t gitea.simplysyncedllc.com/dex/kx3dex_radio:latest .
|
|
||||||
docker push gitea.simplysyncedllc.com/dex/kx3dex_radio:latest
|
|
||||||
|
|
||||||
- name: Build Docker for arm64
|
|
||||||
uses: docker/build-push-action@v4
|
|
||||||
if: ${{ gitea.ref_name != 'latest' }}
|
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
platforms: linux/arm64
|
file: ./Dockerfile
|
||||||
build-args: |
|
platforms: |
|
||||||
VERSION=${{ gitea.ref_name }}
|
linux/arm64
|
||||||
push: true
|
push: true
|
||||||
tags: |
|
tags: |
|
||||||
gitea.simplysyncedllc.com/dex/kx3dex_radio:${{ gitea.ref_name }}
|
gitea.simplysyncedllc.com/dex/kx3dex_radio:latest
|
||||||
|
gitea.simplysyncedllc.com/dex/kx3dex_radio:${{steps.set-result.outputs.result}}
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
37
Dockerfile
37
Dockerfile
|
@ -1,34 +1,24 @@
|
||||||
FROM node:20-alpine AS base
|
|
||||||
|
|
||||||
# Install dependencies only when needed
|
# Install dependencies only when needed
|
||||||
FROM base AS deps
|
FROM node:18-alpine3.19 AS deps
|
||||||
RUN apk add --no-cache libc6-compat
|
RUN apk add --no-cache libc6-compat
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
COPY package.json yarn.lock ./
|
||||||
# Install dependencies based on the preferred package manager
|
RUN yarn config set network-timeout 100000
|
||||||
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
|
RUN yarn install
|
||||||
RUN \
|
|
||||||
if [ -f yarn.lock ]; then yarn; \
|
|
||||||
elif [ -f package-lock.json ]; then npm ci; \
|
|
||||||
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
|
|
||||||
else echo "Lockfile not found." && exit 1; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Rebuild the source code only when needed
|
# Rebuild the source code only when needed
|
||||||
FROM base AS builder
|
FROM node:18-alpine3.19 AS builder
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY --from=deps /app/node_modules ./node_modules
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
RUN \
|
RUN yarn build
|
||||||
if [ -f yarn.lock ]; then yarn run build; \
|
|
||||||
elif [ -f package-lock.json ]; then npm run build; \
|
|
||||||
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
|
|
||||||
else echo "Lockfile not found." && exit 1; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Production image, copy all the files and run next
|
# Production image, copy all the files and run next
|
||||||
FROM base AS runner
|
FROM node:18-alpine3.19 AS runner
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
ENV NODE_ENV production
|
ENV NODE_ENV production
|
||||||
|
@ -37,11 +27,7 @@ RUN addgroup --system --gid 1001 kx3dex_radio
|
||||||
RUN adduser --system --uid 1001 kx3dex_radio
|
RUN adduser --system --uid 1001 kx3dex_radio
|
||||||
|
|
||||||
COPY --from=builder /app/public ./public
|
COPY --from=builder /app/public ./public
|
||||||
# COPY --from=builder /app/package.json ./package.json
|
COPY --from=builder /app/package.json ./package.json
|
||||||
|
|
||||||
# Set the correct permission for prerender cache
|
|
||||||
RUN mkdir .next
|
|
||||||
RUN chown kx3dex_radio:kx3dex_radio .next
|
|
||||||
|
|
||||||
# Automatically leverage output traces to reduce image size
|
# Automatically leverage output traces to reduce image size
|
||||||
# https://nextjs.org/docs/advanced-features/output-file-tracing
|
# https://nextjs.org/docs/advanced-features/output-file-tracing
|
||||||
|
@ -56,4 +42,3 @@ ENV PORT 3000
|
||||||
ENV HOSTNAME "0.0.0.0"
|
ENV HOSTNAME "0.0.0.0"
|
||||||
|
|
||||||
CMD ["node", "server.js"]
|
CMD ["node", "server.js"]
|
||||||
#CMD HOSTNAME="0.0.0.0" node server.js
|
|
|
@ -1,40 +0,0 @@
|
||||||
"use client"
|
|
||||||
|
|
||||||
import * as React from "react"
|
|
||||||
import { MoonIcon, SunIcon } from "@radix-ui/react-icons"
|
|
||||||
import { useTheme } from "next-themes"
|
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button"
|
|
||||||
import {
|
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuItem,
|
|
||||||
DropdownMenuTrigger,
|
|
||||||
} from "@/components/ui/dropdown-menu"
|
|
||||||
|
|
||||||
export function ModeToggle() {
|
|
||||||
const { setTheme } = useTheme()
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<Button variant="outline" size="icon">
|
|
||||||
<SunIcon className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
|
|
||||||
<MoonIcon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
|
|
||||||
<span className="sr-only">Toggle theme</span>
|
|
||||||
</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent align="end">
|
|
||||||
<DropdownMenuItem onClick={() => setTheme("light")}>
|
|
||||||
Light
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem onClick={() => setTheme("dark")}>
|
|
||||||
Dark
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem onClick={() => setTheme("system")}>
|
|
||||||
System
|
|
||||||
</DropdownMenuItem>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -7,7 +7,7 @@ export default function DexNetPage() {
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-2xl font-black text-center mb-10">DexNet VHF/UHF Comm Plan Guide</h1>
|
<h1 className="text-2xl font-black text-center mb-10">DexNet VHF/UHF Comm Plan Guide</h1>
|
||||||
|
|
||||||
<p className="text-lg">With the crazyness of the world I thought it would be worth while to have a communications plan for family and close personal friends. There are many out there such as the S2 Underground for HF communications and a net. However, I did not see much in terms of a more localized one. So I set out to do just that. I have attached the file in a PDF format to be printed. The print is designed to be cut out and placed in 4in x 6in laminating pouches. Before laminating the pouches there are sections to be filled out and decided upon by those in your communications group. Personally I used a hold punch in the top left and used a small caribeener to hold them together.</p>
|
<p className="text-lg">With the crazyness of the world I thought it would be worth while to have a communications plan for family and close personal friends. There are many other guides out there such as the S2 Underground for HF communications and a net. However, I did not see much in terms of a more localized one. So I set out to do just that. I have attached the file in a PDF format to be printed. The print is designed to be cut out and placed in 4in x 6in laminating pouches. Before laminating the pouches there are sections to be filled out and decided upon by those in your communications group. Personally I used a hole punch in the top left and used a small caribeener to hold them together.</p>
|
||||||
<div className="flex align-center justify-center">
|
<div className="flex align-center justify-center">
|
||||||
<Image
|
<Image
|
||||||
src={dexnet_cover}
|
src={dexnet_cover}
|
||||||
|
@ -19,7 +19,7 @@ export default function DexNetPage() {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<h2 className="text-xl font-black text-center mt-10">
|
<h2 className="text-xl font-black text-center mt-10">
|
||||||
<Link href="#">Download Here - LINK COMING SOON</Link>
|
<Link href="KX3DEX_DexNet_v1.pdf">Download Version 1</Link>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,70 +2,55 @@
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
:root {
|
:root {
|
||||||
--background: 0 0% 100%;
|
--background: 0 0% 100%;
|
||||||
--foreground: 222.2 84% 4.9%;
|
--foreground: 240 10% 3.9%;
|
||||||
|
|
||||||
--card: 0 0% 100%;
|
--card: 0 0% 100%;
|
||||||
--card-foreground: 222.2 84% 4.9%;
|
--card-foreground: 240 10% 3.9%;
|
||||||
|
|
||||||
--popover: 0 0% 100%;
|
--popover: 0 0% 100%;
|
||||||
--popover-foreground: 222.2 84% 4.9%;
|
--popover-foreground: 240 10% 3.9%;
|
||||||
|
--primary: 240 5.9% 10%;
|
||||||
--primary: 222.2 47.4% 11.2%;
|
--primary-foreground: 0 0% 98%;
|
||||||
--primary-foreground: 210 40% 98%;
|
--secondary: 240 4.8% 95.9%;
|
||||||
|
--secondary-foreground: 240 5.9% 10%;
|
||||||
--secondary: 210 40% 96.1%;
|
--muted: 240 4.8% 95.9%;
|
||||||
--secondary-foreground: 222.2 47.4% 11.2%;
|
--muted-foreground: 240 3.8% 46.1%;
|
||||||
|
--accent: 240 4.8% 95.9%;
|
||||||
--muted: 210 40% 96.1%;
|
--accent-foreground: 240 5.9% 10%;
|
||||||
--muted-foreground: 215.4 16.3% 46.9%;
|
|
||||||
|
|
||||||
--accent: 210 40% 96.1%;
|
|
||||||
--accent-foreground: 222.2 47.4% 11.2%;
|
|
||||||
|
|
||||||
--destructive: 0 84.2% 60.2%;
|
--destructive: 0 84.2% 60.2%;
|
||||||
--destructive-foreground: 210 40% 98%;
|
--destructive-foreground: 0 0% 98%;
|
||||||
|
--border: 240 5.9% 90%;
|
||||||
--border: 214.3 31.8% 91.4%;
|
--input: 240 5.9% 90%;
|
||||||
--input: 214.3 31.8% 91.4%;
|
--ring: 240 5.9% 10%;
|
||||||
--ring: 222.2 84% 4.9%;
|
|
||||||
|
|
||||||
--radius: 0.5rem;
|
--radius: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
--background: 222.2 84% 4.9%;
|
--background: 240 10% 3.9%;
|
||||||
--foreground: 210 40% 98%;
|
--foreground: 0 0% 98%;
|
||||||
|
--card: 240 10% 3.9%;
|
||||||
--card: 222.2 84% 4.9%;
|
--card-foreground: 0 0% 98%;
|
||||||
--card-foreground: 210 40% 98%;
|
--popover: 240 10% 3.9%;
|
||||||
|
--popover-foreground: 0 0% 98%;
|
||||||
--popover: 222.2 84% 4.9%;
|
--primary: 0 0% 98%;
|
||||||
--popover-foreground: 210 40% 98%;
|
--primary-foreground: 240 5.9% 10%;
|
||||||
|
--secondary: 240 3.7% 15.9%;
|
||||||
--primary: 210 40% 98%;
|
--secondary-foreground: 0 0% 98%;
|
||||||
--primary-foreground: 222.2 47.4% 11.2%;
|
--muted: 240 3.7% 15.9%;
|
||||||
|
--muted-foreground: 240 5% 64.9%;
|
||||||
--secondary: 217.2 32.6% 17.5%;
|
--accent: 240 3.7% 15.9%;
|
||||||
--secondary-foreground: 210 40% 98%;
|
--accent-foreground: 0 0% 98%;
|
||||||
|
|
||||||
--muted: 217.2 32.6% 17.5%;
|
|
||||||
--muted-foreground: 215 20.2% 65.1%;
|
|
||||||
|
|
||||||
--accent: 217.2 32.6% 17.5%;
|
|
||||||
--accent-foreground: 210 40% 98%;
|
|
||||||
|
|
||||||
--destructive: 0 62.8% 30.6%;
|
--destructive: 0 62.8% 30.6%;
|
||||||
--destructive-foreground: 210 40% 98%;
|
--destructive-foreground: 0 0% 98%;
|
||||||
|
--border: 240 3.7% 15.9%;
|
||||||
--border: 217.2 32.6% 17.5%;
|
--input: 240 3.7% 15.9%;
|
||||||
--input: 217.2 32.6% 17.5%;
|
--ring: 240 4.9% 83.9%;
|
||||||
--ring: 212.7 26.8% 83.9%;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
* {
|
* {
|
||||||
@apply border-border;
|
@apply border-border;
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
|
import "./globals.css";
|
||||||
|
|
||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
import React from 'react';
|
|
||||||
import { Inter } from "next/font/google";
|
import { Inter } from "next/font/google";
|
||||||
import "./globals.css";
|
|
||||||
import { ThemeProvider } from "./components/theme-provider";
|
import { ThemeProvider } from "./components/theme-provider";
|
||||||
import Header from "@/components/ui/header";
|
import Header from '@/components/header'
|
||||||
import Footer from "@/components/ui/footer";
|
import HeaderMobile from '@/components/header-mobile'
|
||||||
|
import Footer from "@/components/footer";
|
||||||
|
import MarginWidthWrapper from '@/components/margin-width-wrapper';
|
||||||
|
import PageWrapper from '@/components/page-wrapper';
|
||||||
|
|
||||||
const inter = Inter({ subsets: ["latin"] });
|
const inter = Inter({ subsets: ["latin"] });
|
||||||
|
|
||||||
|
@ -36,9 +39,12 @@ export default function RootLayout({
|
||||||
fill
|
fill
|
||||||
style={{ position: 'absolute' }}
|
style={{ position: 'absolute' }}
|
||||||
/>
|
/>
|
||||||
<Header />
|
<main className="max-w-5xl mx-auto px-4 z-10">
|
||||||
<main className="max-w-5xl mx-auto px-4 z-10">{children}</main>
|
<Header />
|
||||||
<Footer />
|
<HeaderMobile />
|
||||||
|
{children}
|
||||||
|
<Footer />
|
||||||
|
</main>
|
||||||
</div>
|
</div>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</body>
|
</body>
|
||||||
|
|
14
app/page.tsx
14
app/page.tsx
|
@ -1,10 +1,16 @@
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
|
|
||||||
export default async function Home() {
|
export default async function Home() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="grid grid-cols-1 md:grid-cols-1 mt-5 gap-5">
|
<div>
|
||||||
This is my little corner of the internet to share my radio projects on things I'm doing. Things I find and build that seem to not be documented anywhere. I have created pages for some of the projects I have done such as a communcations plan template. Also my go kit builds.
|
<div className="grid grid-cols-1 md:grid-cols-1 mt-5 gap-5">
|
||||||
|
This is my little corner of the internet to share my radio projects on things I'm doing. Things I find and build that seem to not be documented anywhere. I have created pages for some of the projects I have done such as a communcations plan template. Also my go kit builds.
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-1 mt-5 gap-5">
|
||||||
|
if there is anything you have for suggestions on projects you'd like to see a writeup on email me at bluebulletrl@gmail.com. Still need to setup email for this domain.
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-1 mt-5 gap-5">
|
||||||
|
Coming soon will be an updated DexNet guide that will include Meshtastic Information. New document will be uploaded End of August.
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Drawer as DrawerPrimitive } from "vaul"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const Drawer = ({
|
||||||
|
shouldScaleBackground = true,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof DrawerPrimitive.Root>) => (
|
||||||
|
<DrawerPrimitive.Root
|
||||||
|
shouldScaleBackground={shouldScaleBackground}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
Drawer.displayName = "Drawer"
|
||||||
|
|
||||||
|
const DrawerTrigger = DrawerPrimitive.Trigger
|
||||||
|
|
||||||
|
const DrawerPortal = DrawerPrimitive.Portal
|
||||||
|
|
||||||
|
const DrawerClose = DrawerPrimitive.Close
|
||||||
|
|
||||||
|
const DrawerOverlay = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DrawerPrimitive.Overlay>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Overlay>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<DrawerPrimitive.Overlay
|
||||||
|
ref={ref}
|
||||||
|
className={cn("fixed inset-0 z-50 bg-black/80", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName
|
||||||
|
|
||||||
|
const DrawerContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DrawerPrimitive.Content>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Content>
|
||||||
|
>(({ className, children, ...props }, ref) => (
|
||||||
|
<DrawerPortal>
|
||||||
|
<DrawerOverlay />
|
||||||
|
<DrawerPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<div className="mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted" />
|
||||||
|
{children}
|
||||||
|
</DrawerPrimitive.Content>
|
||||||
|
</DrawerPortal>
|
||||||
|
))
|
||||||
|
DrawerContent.displayName = "DrawerContent"
|
||||||
|
|
||||||
|
const DrawerHeader = ({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||||
|
<div
|
||||||
|
className={cn("grid gap-1.5 p-4 text-center sm:text-left", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
DrawerHeader.displayName = "DrawerHeader"
|
||||||
|
|
||||||
|
const DrawerFooter = ({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||||
|
<div
|
||||||
|
className={cn("mt-auto flex flex-col gap-2 p-4", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
DrawerFooter.displayName = "DrawerFooter"
|
||||||
|
|
||||||
|
const DrawerTitle = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DrawerPrimitive.Title>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Title>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<DrawerPrimitive.Title
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"text-lg font-semibold leading-none tracking-tight",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
DrawerTitle.displayName = DrawerPrimitive.Title.displayName
|
||||||
|
|
||||||
|
const DrawerDescription = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DrawerPrimitive.Description>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Description>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<DrawerPrimitive.Description
|
||||||
|
ref={ref}
|
||||||
|
className={cn("text-sm text-muted-foreground", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
DrawerDescription.displayName = DrawerPrimitive.Description.displayName
|
||||||
|
|
||||||
|
export {
|
||||||
|
Drawer,
|
||||||
|
DrawerPortal,
|
||||||
|
DrawerOverlay,
|
||||||
|
DrawerTrigger,
|
||||||
|
DrawerClose,
|
||||||
|
DrawerContent,
|
||||||
|
DrawerHeader,
|
||||||
|
DrawerFooter,
|
||||||
|
DrawerTitle,
|
||||||
|
DrawerDescription,
|
||||||
|
}
|
|
@ -0,0 +1,240 @@
|
||||||
|
'use client';
|
||||||
|
|
||||||
|
import React, { ReactNode, useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
|
import Link from 'next/link';
|
||||||
|
import { usePathname } from 'next/navigation';
|
||||||
|
|
||||||
|
import { NAV_ITEMS } from '@/components/nav';
|
||||||
|
import { NavItem } from '@/components/types';
|
||||||
|
import { Icon } from '@iconify/react';
|
||||||
|
import { motion, useCycle } from 'framer-motion';
|
||||||
|
|
||||||
|
type MenuItemWithSubMenuProps = {
|
||||||
|
item: NavItem;
|
||||||
|
toggleOpen: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const sidebar = {
|
||||||
|
open: (height = 1000) => ({
|
||||||
|
clipPath: `circle(${height * 2 + 200}px at 100% 0)`,
|
||||||
|
transition: {
|
||||||
|
type: 'spring',
|
||||||
|
stiffness: 20,
|
||||||
|
restDelta: 2,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
closed: {
|
||||||
|
clipPath: 'circle(0px at 100% 0)',
|
||||||
|
transition: {
|
||||||
|
type: 'spring',
|
||||||
|
stiffness: 400,
|
||||||
|
damping: 40,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const HeaderMobile = () => {
|
||||||
|
const pathname = usePathname();
|
||||||
|
const containerRef = useRef(null);
|
||||||
|
const { height } = useDimensions(containerRef);
|
||||||
|
const [isOpen, toggleOpen] = useCycle(false, true);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<motion.nav
|
||||||
|
initial={false}
|
||||||
|
animate={isOpen ? 'open' : 'closed'}
|
||||||
|
custom={height}
|
||||||
|
className={`fixed inset-0 z-50 w-full md:hidden ${
|
||||||
|
isOpen ? '' : 'pointer-events-none'
|
||||||
|
}`}
|
||||||
|
ref={containerRef}
|
||||||
|
>
|
||||||
|
<motion.div
|
||||||
|
className="absolute inset-0 right-0 w-full bg-black"
|
||||||
|
variants={sidebar}
|
||||||
|
/>
|
||||||
|
<motion.ul
|
||||||
|
variants={variants}
|
||||||
|
className="absolute grid w-full gap-3 px-10 py-16 max-h-screen overflow-y-auto"
|
||||||
|
>
|
||||||
|
{NAV_ITEMS.map((item, idx) => {
|
||||||
|
const isLastItem = idx === NAV_ITEMS.length - 1; // Check if it's the last item
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div key={idx}>
|
||||||
|
{item.submenu ? (
|
||||||
|
<MenuItemWithSubMenu item={item} toggleOpen={toggleOpen} />
|
||||||
|
) : (
|
||||||
|
<MenuItem>
|
||||||
|
<Link
|
||||||
|
href={item.path}
|
||||||
|
onClick={() => toggleOpen()}
|
||||||
|
className={`flex w-full text-2xl ${
|
||||||
|
item.path === pathname ? 'font-bold' : ''
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{item.title}
|
||||||
|
</Link>
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!isLastItem && (
|
||||||
|
<MenuItem className="my-3 h-px w-full bg-gray-300" />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</motion.ul>
|
||||||
|
<MenuToggle toggle={toggleOpen} />
|
||||||
|
</motion.nav>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default HeaderMobile;
|
||||||
|
|
||||||
|
const MenuToggle = ({ toggle }: { toggle: any }) => (
|
||||||
|
<button
|
||||||
|
onClick={toggle}
|
||||||
|
className="pointer-events-auto absolute right-4 top-[14px] z-30 p-7"
|
||||||
|
>
|
||||||
|
<svg width="60" height="60" viewBox="0 0 23 23">
|
||||||
|
<Path
|
||||||
|
variants={{
|
||||||
|
closed: { d: 'M 2 2.5 L 20 2.5' },
|
||||||
|
open: { d: 'M 3 16.5 L 17 2.5' },
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
d="M 2 9.423 L 20 9.423"
|
||||||
|
variants={{
|
||||||
|
closed: { opacity: 1 },
|
||||||
|
open: { opacity: 0 },
|
||||||
|
}}
|
||||||
|
transition={{ duration: 0.1 }}
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
variants={{
|
||||||
|
closed: { d: 'M 2 16.346 L 20 16.346' },
|
||||||
|
open: { d: 'M 3 2.5 L 17 16.346' },
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
|
||||||
|
const Path = (props: any) => (
|
||||||
|
<motion.path
|
||||||
|
fill="transparent"
|
||||||
|
strokeWidth="2"
|
||||||
|
stroke="hsl(0, 0%, 100%)"
|
||||||
|
strokeLinecap="round"
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const MenuItem = ({
|
||||||
|
className,
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
className?: string;
|
||||||
|
children?: ReactNode;
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<motion.li variants={MenuItemVariants} className={className}>
|
||||||
|
{children}
|
||||||
|
</motion.li>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const MenuItemWithSubMenu: React.FC<MenuItemWithSubMenuProps> = ({
|
||||||
|
item,
|
||||||
|
toggleOpen,
|
||||||
|
}) => {
|
||||||
|
const pathname = usePathname();
|
||||||
|
const [subMenuOpen, setSubMenuOpen] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<MenuItem>
|
||||||
|
<button
|
||||||
|
className="flex w-full text-2xl"
|
||||||
|
onClick={() => setSubMenuOpen(!subMenuOpen)}
|
||||||
|
>
|
||||||
|
<div className="flex flex-row justify-between w-full items-center">
|
||||||
|
<span
|
||||||
|
className={`${pathname.includes(item.path) ? 'font-bold' : ''}`}
|
||||||
|
>
|
||||||
|
{item.title}
|
||||||
|
</span>
|
||||||
|
<div className={`${subMenuOpen && 'rotate-180'}`}>
|
||||||
|
<Icon icon="lucide:chevron-down" width="24" height="24" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</MenuItem>
|
||||||
|
<div className="mt-2 ml-2 flex flex-col space-y-2">
|
||||||
|
{subMenuOpen && (
|
||||||
|
<>
|
||||||
|
{item.subMenuItems?.map((subItem, subIdx) => {
|
||||||
|
return (
|
||||||
|
<MenuItem key={subIdx}>
|
||||||
|
<Link
|
||||||
|
href={subItem.path}
|
||||||
|
onClick={() => toggleOpen()}
|
||||||
|
className={` ${
|
||||||
|
subItem.path === pathname ? 'font-bold' : ''
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{subItem.title}
|
||||||
|
</Link>
|
||||||
|
</MenuItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const MenuItemVariants = {
|
||||||
|
open: {
|
||||||
|
y: 0,
|
||||||
|
opacity: 1,
|
||||||
|
transition: {
|
||||||
|
y: { stiffness: 1000, velocity: -100 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
closed: {
|
||||||
|
y: 50,
|
||||||
|
opacity: 0,
|
||||||
|
transition: {
|
||||||
|
y: { stiffness: 1000 },
|
||||||
|
duration: 0.02,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const variants = {
|
||||||
|
open: {
|
||||||
|
transition: { staggerChildren: 0.02, delayChildren: 0.15 },
|
||||||
|
},
|
||||||
|
closed: {
|
||||||
|
transition: { staggerChildren: 0.01, staggerDirection: -1 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const useDimensions = (ref: any) => {
|
||||||
|
const dimensions = useRef({ width: 0, height: 0 });
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (ref.current) {
|
||||||
|
dimensions.current.width = ref.current.offsetWidth;
|
||||||
|
dimensions.current.height = ref.current.offsetHeight;
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ref]);
|
||||||
|
|
||||||
|
return dimensions.current;
|
||||||
|
};
|
|
@ -0,0 +1,65 @@
|
||||||
|
'use client';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import { useSelectedLayoutSegment } from 'next/navigation';
|
||||||
|
import logo from '@/public/images/kx3dex_radio_logo.png'
|
||||||
|
|
||||||
|
import useScroll from '@/hooks/use-scroll';
|
||||||
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
|
import {
|
||||||
|
NavigationMenu,
|
||||||
|
NavigationMenuContent,
|
||||||
|
NavigationMenuItem,
|
||||||
|
NavigationMenuLink,
|
||||||
|
NavigationMenuList,
|
||||||
|
NavigationMenuTrigger,
|
||||||
|
} from "@/components/navigation-menu"
|
||||||
|
|
||||||
|
const Header = () => {
|
||||||
|
const scrolled = useScroll(5);
|
||||||
|
const selectedLayout = useSelectedLayoutSegment();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
`sticky inset-x-0 top-0 z-30 w-full transition-all border-b border-gray-200`,
|
||||||
|
{
|
||||||
|
'border-b border-gray-200 backdrop-blur-lg': scrolled,
|
||||||
|
'border-b border-gray-200 mb-5': selectedLayout,
|
||||||
|
},
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className="flex items-center justify-between p-4">
|
||||||
|
<div className="flex items-center space-x-4">
|
||||||
|
<Image
|
||||||
|
src={logo}
|
||||||
|
width={100}
|
||||||
|
height={100}
|
||||||
|
alt="Logo Image"
|
||||||
|
priority
|
||||||
|
className="rounded-lg border"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="hidden md:block">
|
||||||
|
<NavigationMenu>
|
||||||
|
<NavigationMenuLink href="/" className="font-bold text-3xl pr-5">Home</NavigationMenuLink>
|
||||||
|
<NavigationMenuLink href="/dexnet" className="font-bold text-3xl pr-5">DexNet</NavigationMenuLink>
|
||||||
|
<NavigationMenuList>
|
||||||
|
<NavigationMenuItem>
|
||||||
|
<NavigationMenuTrigger className="font-bold text-3xl pr-5">Go Kits</NavigationMenuTrigger>
|
||||||
|
<NavigationMenuContent className="flex flex-col min-w-[300px] p-2 absolute right-0">
|
||||||
|
<NavigationMenuLink href="/projects/go-kit-command-center" className="font-bold">Go Kit (Command Center)</NavigationMenuLink>
|
||||||
|
</NavigationMenuContent>
|
||||||
|
</NavigationMenuItem>
|
||||||
|
</NavigationMenuList>
|
||||||
|
</NavigationMenu>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Header;
|
|
@ -0,0 +1,13 @@
|
||||||
|
import { ReactNode } from 'react';
|
||||||
|
|
||||||
|
export default function MarginWidthWrapper({
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
children: ReactNode;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col md:ml-60 sm:border-r sm:border-zinc-700 min-h-screen">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { Icon } from '@iconify/react';
|
||||||
|
|
||||||
|
import { NavItem } from '@/components/types';
|
||||||
|
|
||||||
|
export const NAV_ITEMS: NavItem[] = [
|
||||||
|
{
|
||||||
|
title: 'Home',
|
||||||
|
path: '/',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'DexNet',
|
||||||
|
path: '/dexnet',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Go Kits',
|
||||||
|
path: '',
|
||||||
|
submenu: true,
|
||||||
|
subMenuItems: [
|
||||||
|
{ title: 'Go Kit Command Center', path: '/projects/go-kit-command-center' },
|
||||||
|
],
|
||||||
|
}
|
||||||
|
];
|
|
@ -41,7 +41,7 @@ NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName
|
||||||
const NavigationMenuItem = NavigationMenuPrimitive.Item
|
const NavigationMenuItem = NavigationMenuPrimitive.Item
|
||||||
|
|
||||||
const navigationMenuTriggerStyle = cva(
|
const navigationMenuTriggerStyle = cva(
|
||||||
"group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50"
|
"group inline-flex h-10 w-max items-center justify-center rounded-md yarnpy-2 text-sm font-medium transition-colors focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50"
|
||||||
)
|
)
|
||||||
|
|
||||||
const NavigationMenuTrigger = React.forwardRef<
|
const NavigationMenuTrigger = React.forwardRef<
|
||||||
|
@ -83,10 +83,10 @@ const NavigationMenuViewport = React.forwardRef<
|
||||||
React.ElementRef<typeof NavigationMenuPrimitive.Viewport>,
|
React.ElementRef<typeof NavigationMenuPrimitive.Viewport>,
|
||||||
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Viewport>
|
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Viewport>
|
||||||
>(({ className, ...props }, ref) => (
|
>(({ className, ...props }, ref) => (
|
||||||
<div className={cn("absolute left-0 top-full flex justify-center")}>
|
<div className={cn("absolute right-0 top-full flex ")}>
|
||||||
<NavigationMenuPrimitive.Viewport
|
<NavigationMenuPrimitive.Viewport
|
||||||
className={cn(
|
className={cn(
|
||||||
"origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]",
|
"origin-top-left relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
ref={ref}
|
ref={ref}
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { ReactNode } from 'react';
|
||||||
|
|
||||||
|
export default function PageWrapper({ children }: { children: ReactNode }) {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col pt-2 px-4 space-y-2 bg-zinc-100 flex-grow pb-4">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
export type NavItem = {
|
||||||
|
title: string;
|
||||||
|
path: string;
|
||||||
|
icon?: JSX.Element;
|
||||||
|
submenu?: boolean;
|
||||||
|
subMenuItems?: NavItem[];
|
||||||
|
};
|
|
@ -1,47 +0,0 @@
|
||||||
'use client'
|
|
||||||
import Link from 'next/link'
|
|
||||||
import Image from 'next/image'
|
|
||||||
import logo from '@/public/images/kx3dex_radio_logo.png'
|
|
||||||
|
|
||||||
import {
|
|
||||||
NavigationMenu,
|
|
||||||
NavigationMenuContent,
|
|
||||||
NavigationMenuItem,
|
|
||||||
NavigationMenuLink,
|
|
||||||
NavigationMenuList,
|
|
||||||
NavigationMenuTrigger,
|
|
||||||
} from "@/components/ui/navigation-menu"
|
|
||||||
|
|
||||||
|
|
||||||
export default function Header() {
|
|
||||||
return (
|
|
||||||
<nav className="w-full relative flex items-center max-w-5xl mx-auto px-4 py-5">
|
|
||||||
<Image
|
|
||||||
src={logo}
|
|
||||||
width={100}
|
|
||||||
height={100}
|
|
||||||
alt="Logo Image"
|
|
||||||
priority
|
|
||||||
className="rounded-lg border"
|
|
||||||
/>
|
|
||||||
<Link href="/" className="font-bold text-3xl pl-10 pr-5">
|
|
||||||
Home
|
|
||||||
</Link>
|
|
||||||
<Link href="/dexnet" className="font-bold text-3xl ">
|
|
||||||
DexNet
|
|
||||||
</Link>
|
|
||||||
<NavigationMenu>
|
|
||||||
<NavigationMenuList>
|
|
||||||
<NavigationMenuItem>
|
|
||||||
<NavigationMenuTrigger className="font-bold text-3xl pr-5">Go Kits</NavigationMenuTrigger>
|
|
||||||
<NavigationMenuContent className="flex flex-col min-w-[300px] p-2">
|
|
||||||
<NavigationMenuLink href="/projects/go-kit-command-center" className="font-bold">Go Kit (Command Center)</NavigationMenuLink>
|
|
||||||
</NavigationMenuContent>
|
|
||||||
</NavigationMenuItem>
|
|
||||||
</NavigationMenuList>
|
|
||||||
</NavigationMenu>
|
|
||||||
</nav>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
export default function useScroll(threshold: number) {
|
||||||
|
const [scrolled, setScrolled] = useState(false);
|
||||||
|
|
||||||
|
const onScroll = useCallback(() => {
|
||||||
|
setScrolled(window.scrollY > threshold);
|
||||||
|
}, [threshold]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.addEventListener('scroll', onScroll);
|
||||||
|
return () => window.removeEventListener('scroll', onScroll);
|
||||||
|
}, [onScroll]);
|
||||||
|
|
||||||
|
// also check on first load
|
||||||
|
useEffect(() => {
|
||||||
|
onScroll();
|
||||||
|
}, [onScroll]);
|
||||||
|
|
||||||
|
return scrolled;
|
||||||
|
}
|
|
@ -8,20 +8,25 @@
|
||||||
"name": "kx3dex_radio",
|
"name": "kx3dex_radio",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@iconify/react": "^4.1.1",
|
||||||
|
"@radix-ui/react-dialog": "^1.0.5",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.0.6",
|
"@radix-ui/react-dropdown-menu": "^2.0.6",
|
||||||
"@radix-ui/react-icons": "^1.3.0",
|
"@radix-ui/react-icons": "^1.3.0",
|
||||||
"@radix-ui/react-navigation-menu": "^1.1.4",
|
"@radix-ui/react-navigation-menu": "^1.1.4",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"clsx": "^2.1.0",
|
"clsx": "^2.1.0",
|
||||||
|
"framer-motion": "^11.0.27",
|
||||||
"lucide-react": "^0.363.0",
|
"lucide-react": "^0.363.0",
|
||||||
"next": "14.1.4",
|
"next": "14.1.4",
|
||||||
"next-themes": "^0.3.0",
|
"next-themes": "^0.3.0",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
|
"react-icons": "^5.0.1",
|
||||||
"sharp": "^0.33.3",
|
"sharp": "^0.33.3",
|
||||||
"swiper": "^11.1.0",
|
"swiper": "^11.1.0",
|
||||||
"tailwind-merge": "^2.2.2",
|
"tailwind-merge": "^2.2.2",
|
||||||
"tailwindcss-animate": "^1.0.7"
|
"tailwindcss-animate": "^1.0.7",
|
||||||
|
"vaul": "^0.9.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
|
@ -198,6 +203,25 @@
|
||||||
"integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==",
|
"integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@iconify/react": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@iconify/react/-/react-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-jed14EjvKjee8mc0eoscGxlg7mSQRkwQG3iX3cPBCO7UlOjz0DtlvTqxqEcHUJGh+z1VJ31Yhu5B9PxfO0zbdg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@iconify/types": "^2.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/cyberalien"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@iconify/types": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="
|
||||||
|
},
|
||||||
"node_modules/@img/sharp-darwin-arm64": {
|
"node_modules/@img/sharp-darwin-arm64": {
|
||||||
"version": "0.33.3",
|
"version": "0.33.3",
|
||||||
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.3.tgz",
|
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.3.tgz",
|
||||||
|
@ -994,6 +1018,42 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@radix-ui/react-dialog": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.13.10",
|
||||||
|
"@radix-ui/primitive": "1.0.1",
|
||||||
|
"@radix-ui/react-compose-refs": "1.0.1",
|
||||||
|
"@radix-ui/react-context": "1.0.1",
|
||||||
|
"@radix-ui/react-dismissable-layer": "1.0.5",
|
||||||
|
"@radix-ui/react-focus-guards": "1.0.1",
|
||||||
|
"@radix-ui/react-focus-scope": "1.0.4",
|
||||||
|
"@radix-ui/react-id": "1.0.1",
|
||||||
|
"@radix-ui/react-portal": "1.0.4",
|
||||||
|
"@radix-ui/react-presence": "1.0.1",
|
||||||
|
"@radix-ui/react-primitive": "1.0.3",
|
||||||
|
"@radix-ui/react-slot": "1.0.2",
|
||||||
|
"@radix-ui/react-use-controllable-state": "1.0.1",
|
||||||
|
"aria-hidden": "^1.1.1",
|
||||||
|
"react-remove-scroll": "2.5.5"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-dom": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0",
|
||||||
|
"react-dom": "^16.8 || ^17.0 || ^18.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@radix-ui/react-direction": {
|
"node_modules/@radix-ui/react-direction": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.1.tgz",
|
||||||
|
@ -3290,6 +3350,30 @@
|
||||||
"url": "https://github.com/sponsors/rawify"
|
"url": "https://github.com/sponsors/rawify"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/framer-motion": {
|
||||||
|
"version": "11.0.27",
|
||||||
|
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.0.27.tgz",
|
||||||
|
"integrity": "sha512-OmY1hnBXxUfvQTuoPqumAiXYPEt8jY31Fqbmihf/NR29XUL9BkRPHrqVqtJS7TLKriwRt+0pbwiO9tnziZTJzA==",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@emotion/is-prop-valid": "*",
|
||||||
|
"react": "^18.0.0",
|
||||||
|
"react-dom": "^18.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@emotion/is-prop-valid": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fs.realpath": {
|
"node_modules/fs.realpath": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||||
|
@ -4957,6 +5041,14 @@
|
||||||
"react": "^18.2.0"
|
"react": "^18.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-icons": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-WqLZJ4bLzlhmsvme6iFdgO8gfZP17rfjYEJ2m9RsZjZ+cc4k1hTzknEz63YS1MeT50kVzoa1Nz36f4BEx+Wigw==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-is": {
|
"node_modules/react-is": {
|
||||||
"version": "16.13.1",
|
"version": "16.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
|
@ -6027,6 +6119,18 @@
|
||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/vaul": {
|
||||||
|
"version": "0.9.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vaul/-/vaul-0.9.0.tgz",
|
||||||
|
"integrity": "sha512-bZSySGbAHiTXmZychprnX/dE0EsSige88xtyyL3/MCRbrFotRPQZo7UdydGXZWw+CKbNOw5Ow8gwAo93/nB/Cg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/react-dialog": "^1.0.4"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0",
|
||||||
|
"react-dom": "^16.8 || ^17.0 || ^18.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/which": {
|
"node_modules/which": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "kx3dex_radio",
|
"name": "kx3dex_radio",
|
||||||
"version": "1.0.0",
|
"version": "1.3.5",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
|
@ -9,20 +9,25 @@
|
||||||
"lint": "next lint"
|
"lint": "next lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@iconify/react": "^4.1.1",
|
||||||
|
"@radix-ui/react-dialog": "^1.0.5",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.0.6",
|
"@radix-ui/react-dropdown-menu": "^2.0.6",
|
||||||
"@radix-ui/react-icons": "^1.3.0",
|
"@radix-ui/react-icons": "^1.3.0",
|
||||||
"@radix-ui/react-navigation-menu": "^1.1.4",
|
"@radix-ui/react-navigation-menu": "^1.1.4",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"clsx": "^2.1.0",
|
"clsx": "^2.1.0",
|
||||||
|
"framer-motion": "^11.0.27",
|
||||||
"lucide-react": "^0.363.0",
|
"lucide-react": "^0.363.0",
|
||||||
"next": "14.1.4",
|
"next": "14.1.4",
|
||||||
"next-themes": "^0.3.0",
|
"next-themes": "^0.3.0",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
|
"react-icons": "^5.0.1",
|
||||||
"sharp": "^0.33.3",
|
"sharp": "^0.33.3",
|
||||||
"swiper": "^11.1.0",
|
"swiper": "^11.1.0",
|
||||||
"tailwind-merge": "^2.2.2",
|
"tailwind-merge": "^2.2.2",
|
||||||
"tailwindcss-animate": "^1.0.7"
|
"tailwindcss-animate": "^1.0.7",
|
||||||
|
"vaul": "^0.9.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
|
|
Binary file not shown.
135
yarn.lock
135
yarn.lock
|
@ -29,11 +29,11 @@ __metadata:
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@emnapi/runtime@npm:^1.1.0":
|
"@emnapi/runtime@npm:^1.1.0":
|
||||||
version: 1.1.0
|
version: 1.1.1
|
||||||
resolution: "@emnapi/runtime@npm:1.1.0"
|
resolution: "@emnapi/runtime@npm:1.1.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib: ^2.4.0
|
tslib: ^2.4.0
|
||||||
checksum: a29917ac2ab20276c416244a0866b4628e50cb7bb9219a1bd51f48c5328d3565a78f5aa97cc81fa8fad8d06356b5274c551744da94184b2495be6b081da829c3
|
checksum: db5ec075a8fa71d7dbbba8592c8edfed073dfe5181a87bde56f92693985c548be5be3a66c6bd656e41b7f23d0af20d59e55684a81aecc5d2977f74ed24cbe3fe
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -142,6 +142,24 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@iconify/react@npm:^4.1.1":
|
||||||
|
version: 4.1.1
|
||||||
|
resolution: "@iconify/react@npm:4.1.1"
|
||||||
|
dependencies:
|
||||||
|
"@iconify/types": ^2.0.0
|
||||||
|
peerDependencies:
|
||||||
|
react: ">=16"
|
||||||
|
checksum: 43b71a0eb4312cf0fa7412b568369e75b8a327b8b7d9fc3dce42b2d047326e39dd17541a8d915fb80b87b20a56eba1a9b52304410624b5814fdf3ad17da9196a
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@iconify/types@npm:^2.0.0":
|
||||||
|
version: 2.0.0
|
||||||
|
resolution: "@iconify/types@npm:2.0.0"
|
||||||
|
checksum: 029f58542c160e9d4a746869cf2e475b603424d3adf3994c5cc8d0406c47e6e04a3b898b2707840c1c5b9bd5563a1660a34b110d89fce43923baca5222f4e597
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@img/sharp-darwin-arm64@npm:0.33.3":
|
"@img/sharp-darwin-arm64@npm:0.33.3":
|
||||||
version: 0.33.3
|
version: 0.33.3
|
||||||
resolution: "@img/sharp-darwin-arm64@npm:0.33.3"
|
resolution: "@img/sharp-darwin-arm64@npm:0.33.3"
|
||||||
|
@ -480,15 +498,15 @@ __metadata:
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@npmcli/agent@npm:^2.0.0":
|
"@npmcli/agent@npm:^2.0.0":
|
||||||
version: 2.2.1
|
version: 2.2.2
|
||||||
resolution: "@npmcli/agent@npm:2.2.1"
|
resolution: "@npmcli/agent@npm:2.2.2"
|
||||||
dependencies:
|
dependencies:
|
||||||
agent-base: ^7.1.0
|
agent-base: ^7.1.0
|
||||||
http-proxy-agent: ^7.0.0
|
http-proxy-agent: ^7.0.0
|
||||||
https-proxy-agent: ^7.0.1
|
https-proxy-agent: ^7.0.1
|
||||||
lru-cache: ^10.0.1
|
lru-cache: ^10.0.1
|
||||||
socks-proxy-agent: ^8.0.1
|
socks-proxy-agent: ^8.0.3
|
||||||
checksum: c69aca42dbba393f517bc5777ee872d38dc98ea0e5e93c1f6d62b82b8fecdc177a57ea045f07dda1a770c592384b2dd92a5e79e21e2a7cf51c9159466a8f9c9b
|
checksum: 67de7b88cc627a79743c88bab35e023e23daf13831a8aa4e15f998b92f5507b644d8ffc3788afc8e64423c612e0785a6a92b74782ce368f49a6746084b50d874
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -590,6 +608,39 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@radix-ui/react-dialog@npm:^1.0.4, @radix-ui/react-dialog@npm:^1.0.5":
|
||||||
|
version: 1.0.5
|
||||||
|
resolution: "@radix-ui/react-dialog@npm:1.0.5"
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime": ^7.13.10
|
||||||
|
"@radix-ui/primitive": 1.0.1
|
||||||
|
"@radix-ui/react-compose-refs": 1.0.1
|
||||||
|
"@radix-ui/react-context": 1.0.1
|
||||||
|
"@radix-ui/react-dismissable-layer": 1.0.5
|
||||||
|
"@radix-ui/react-focus-guards": 1.0.1
|
||||||
|
"@radix-ui/react-focus-scope": 1.0.4
|
||||||
|
"@radix-ui/react-id": 1.0.1
|
||||||
|
"@radix-ui/react-portal": 1.0.4
|
||||||
|
"@radix-ui/react-presence": 1.0.1
|
||||||
|
"@radix-ui/react-primitive": 1.0.3
|
||||||
|
"@radix-ui/react-slot": 1.0.2
|
||||||
|
"@radix-ui/react-use-controllable-state": 1.0.1
|
||||||
|
aria-hidden: ^1.1.1
|
||||||
|
react-remove-scroll: 2.5.5
|
||||||
|
peerDependencies:
|
||||||
|
"@types/react": "*"
|
||||||
|
"@types/react-dom": "*"
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
"@types/react":
|
||||||
|
optional: true
|
||||||
|
"@types/react-dom":
|
||||||
|
optional: true
|
||||||
|
checksum: 3d11ca31afb794a6dd286005ab7894cb0ce7bc2de5481de98900470b11d495256401306763de030f5e35aa545ff90d34632ffd54a1b29bf55afba813be4bb84a
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@radix-ui/react-direction@npm:1.0.1":
|
"@radix-ui/react-direction@npm:1.0.1":
|
||||||
version: 1.0.1
|
version: 1.0.1
|
||||||
resolution: "@radix-ui/react-direction@npm:1.0.1"
|
resolution: "@radix-ui/react-direction@npm:1.0.1"
|
||||||
|
@ -1213,12 +1264,12 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0":
|
"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0, agent-base@npm:^7.1.1":
|
||||||
version: 7.1.0
|
version: 7.1.1
|
||||||
resolution: "agent-base@npm:7.1.0"
|
resolution: "agent-base@npm:7.1.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: ^4.3.4
|
debug: ^4.3.4
|
||||||
checksum: f7828f991470a0cc22cb579c86a18cbae83d8a3cbed39992ab34fc7217c4d126017f1c74d0ab66be87f71455318a8ea3e757d6a37881b8d0f2a2c6aa55e5418f
|
checksum: 51c158769c5c051482f9ca2e6e1ec085ac72b5a418a9b31b4e82fe6c0a6699adb94c1c42d246699a587b3335215037091c79e0de512c516f73b6ea844202f037
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -2509,6 +2560,26 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"framer-motion@npm:^11.0.27":
|
||||||
|
version: 11.0.27
|
||||||
|
resolution: "framer-motion@npm:11.0.27"
|
||||||
|
dependencies:
|
||||||
|
tslib: ^2.4.0
|
||||||
|
peerDependencies:
|
||||||
|
"@emotion/is-prop-valid": "*"
|
||||||
|
react: ^18.0.0
|
||||||
|
react-dom: ^18.0.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
"@emotion/is-prop-valid":
|
||||||
|
optional: true
|
||||||
|
react:
|
||||||
|
optional: true
|
||||||
|
react-dom:
|
||||||
|
optional: true
|
||||||
|
checksum: 07809e386288350547bd9193143d9e33e6ab2d1357152b4d90acf50a445437b59ddb1653dcedde75579d3af8c7904c158fdfa6ad97d65786855eb002634bb38b
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"fs-minipass@npm:^2.0.0":
|
"fs-minipass@npm:^2.0.0":
|
||||||
version: 2.1.0
|
version: 2.1.0
|
||||||
resolution: "fs-minipass@npm:2.1.0"
|
resolution: "fs-minipass@npm:2.1.0"
|
||||||
|
@ -3295,6 +3366,8 @@ __metadata:
|
||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "kx3dex_radio@workspace:."
|
resolution: "kx3dex_radio@workspace:."
|
||||||
dependencies:
|
dependencies:
|
||||||
|
"@iconify/react": ^4.1.1
|
||||||
|
"@radix-ui/react-dialog": ^1.0.5
|
||||||
"@radix-ui/react-dropdown-menu": ^2.0.6
|
"@radix-ui/react-dropdown-menu": ^2.0.6
|
||||||
"@radix-ui/react-icons": ^1.3.0
|
"@radix-ui/react-icons": ^1.3.0
|
||||||
"@radix-ui/react-navigation-menu": ^1.1.4
|
"@radix-ui/react-navigation-menu": ^1.1.4
|
||||||
|
@ -3306,18 +3379,21 @@ __metadata:
|
||||||
clsx: ^2.1.0
|
clsx: ^2.1.0
|
||||||
eslint: ^8
|
eslint: ^8
|
||||||
eslint-config-next: 14.1.4
|
eslint-config-next: 14.1.4
|
||||||
|
framer-motion: ^11.0.27
|
||||||
lucide-react: ^0.363.0
|
lucide-react: ^0.363.0
|
||||||
next: 14.1.4
|
next: 14.1.4
|
||||||
next-themes: ^0.3.0
|
next-themes: ^0.3.0
|
||||||
postcss: ^8
|
postcss: ^8
|
||||||
react: ^18
|
react: ^18
|
||||||
react-dom: ^18
|
react-dom: ^18
|
||||||
|
react-icons: ^5.0.1
|
||||||
sharp: ^0.33.3
|
sharp: ^0.33.3
|
||||||
swiper: ^11.1.0
|
swiper: ^11.1.0
|
||||||
tailwind-merge: ^2.2.2
|
tailwind-merge: ^2.2.2
|
||||||
tailwindcss: ^3.4.1
|
tailwindcss: ^3.4.1
|
||||||
tailwindcss-animate: ^1.0.7
|
tailwindcss-animate: ^1.0.7
|
||||||
typescript: ^5
|
typescript: ^5
|
||||||
|
vaul: ^0.9.0
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
|
@ -4120,6 +4196,15 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"react-icons@npm:^5.0.1":
|
||||||
|
version: 5.0.1
|
||||||
|
resolution: "react-icons@npm:5.0.1"
|
||||||
|
peerDependencies:
|
||||||
|
react: "*"
|
||||||
|
checksum: e5df9c5e3bcdb8d68bd4c5e41650c26d2a3ceda61ded0e2abf7caa0e54c9fb712badcd06f0c240cfc645a5dd15a5dc1eb5dd55f60123d86860f516b1fc456474
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"react-is@npm:^16.13.1":
|
"react-is@npm:^16.13.1":
|
||||||
version: 16.13.1
|
version: 16.13.1
|
||||||
resolution: "react-is@npm:16.13.1"
|
resolution: "react-is@npm:16.13.1"
|
||||||
|
@ -4552,24 +4637,24 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"socks-proxy-agent@npm:^8.0.1":
|
"socks-proxy-agent@npm:^8.0.3":
|
||||||
version: 8.0.2
|
version: 8.0.3
|
||||||
resolution: "socks-proxy-agent@npm:8.0.2"
|
resolution: "socks-proxy-agent@npm:8.0.3"
|
||||||
dependencies:
|
dependencies:
|
||||||
agent-base: ^7.0.2
|
agent-base: ^7.1.1
|
||||||
debug: ^4.3.4
|
debug: ^4.3.4
|
||||||
socks: ^2.7.1
|
socks: ^2.7.1
|
||||||
checksum: 4fb165df08f1f380881dcd887b3cdfdc1aba3797c76c1e9f51d29048be6e494c5b06d68e7aea2e23df4572428f27a3ec22b3d7c75c570c5346507433899a4b6d
|
checksum: 8fab38821c327c190c28f1658087bc520eb065d55bc07b4a0fdf8d1e0e7ad5d115abbb22a95f94f944723ea969dd771ad6416b1e3cde9060c4c71f705c8b85c5
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"socks@npm:^2.7.1":
|
"socks@npm:^2.7.1":
|
||||||
version: 2.8.1
|
version: 2.8.3
|
||||||
resolution: "socks@npm:2.8.1"
|
resolution: "socks@npm:2.8.3"
|
||||||
dependencies:
|
dependencies:
|
||||||
ip-address: ^9.0.5
|
ip-address: ^9.0.5
|
||||||
smart-buffer: ^4.2.0
|
smart-buffer: ^4.2.0
|
||||||
checksum: 29586d42e9c36c5016632b2bcb6595e3adfbcb694b3a652c51bc8741b079c5ec37bdd5675a1a89a1620078c8137208294991fabb50786f92d47759a725b2b62e
|
checksum: 7a6b7f6eedf7482b9e4597d9a20e09505824208006ea8f2c49b71657427f3c137ca2ae662089baa73e1971c62322d535d9d0cf1c9235cf6f55e315c18203eadd
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -5095,6 +5180,18 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"vaul@npm:^0.9.0":
|
||||||
|
version: 0.9.0
|
||||||
|
resolution: "vaul@npm:0.9.0"
|
||||||
|
dependencies:
|
||||||
|
"@radix-ui/react-dialog": ^1.0.4
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
checksum: 12c4ced1a91400abe8d20c0c2108f2ffe7d81172eb08c3d7a24e9f813a034e00a9ddb43bb30a7ec312e71292d7b15b13d0fd9e866646b35e13b6d8bc61974198
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"which-boxed-primitive@npm:^1.0.2":
|
"which-boxed-primitive@npm:^1.0.2":
|
||||||
version: 1.0.2
|
version: 1.0.2
|
||||||
resolution: "which-boxed-primitive@npm:1.0.2"
|
resolution: "which-boxed-primitive@npm:1.0.2"
|
||||||
|
|
Loading…
Reference in New Issue