Skip to content

Commit 8c31c9d

Browse files
hariHumboorgiramkayondoanshuman008anshuman
authored
feat: release to production (#403)
Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Iliya.Faz <71210624+Humboorgir@users.noreply.github.com> Co-authored-by: Kayondo Edward <46356108+amkayondo@users.noreply.github.com> Co-authored-by: Anshuman <code.anshu@gmail.com> Co-authored-by: anshuman <anshuman@anshumans-MacBook-Air.local> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Daniel Crump <42187710+dancrump1@users.noreply.github.com>
1 parent e2e8560 commit 8c31c9d

9 files changed

Lines changed: 267 additions & 19 deletions

File tree

.github/workflows/deploy.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ jobs:
4141
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ vars.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
4242
NEXT_PUBLIC_POSTHOG_KEY: ${{ vars.NEXT_PUBLIC_POSTHOG_KEY }}
4343
NEXT_PUBLIC_POSTHOG_HOST: ${{ vars.NEXT_PUBLIC_POSTHOG_HOST }}
44+
NEXT_PUBLIC_PLUNK_API_KEY: ${{ vars.NEXT_PUBLIC_PLUNK_API_KEY }}
4445
run: yarn build
4546
- name: Deploy to Cloudflare Pages
4647
id: deploy
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import CalendarWidget from "@/animata/widget/calendar-widget";
2+
import { Meta, StoryObj } from "@storybook/react";
3+
4+
const meta = {
5+
title: "Widget/Calendar Widget",
6+
component: CalendarWidget,
7+
parameters: {
8+
layout: "centered",
9+
},
10+
tags: ["autodocs"],
11+
argTypes: {
12+
initialSelectedDate: {
13+
control: { type: "number", min: 1, max: 30 },
14+
defaultValue: 1,
15+
},
16+
initialShowEvents: {
17+
control: { type: "boolean" },
18+
defaultValue: true,
19+
},
20+
eventsData: {
21+
control: { type: "object" },
22+
defaultValue: [
23+
{ date: 3, title: "Project Review", time: "10:00 - 11:00 AM" },
24+
{ date: 5, title: "Client Meeting", time: "9:00 - 9:45 AM" },
25+
{ date: 18, title: "Walk", time: "6:00 - 7:00 AM" },
26+
],
27+
},
28+
},
29+
} satisfies Meta<typeof CalendarWidget>;
30+
31+
export default meta;
32+
type Story = StoryObj<typeof meta>;
33+
34+
export const Primary: Story = {
35+
args: {
36+
initialSelectedDate: 1,
37+
initialShowEvents: true,
38+
eventsData: [
39+
{ date: 3, title: "Project Review", time: "10:00 - 11:00 AM" },
40+
{ date: 3, title: "Project discussion", time: "11:00 - 12:00 AM" },
41+
{ date: 5, title: "Client Meeting", time: "9:00 - 9:45 AM" },
42+
{ date: 18, title: "Walk", time: "6:00 - 7:00 AM" },
43+
],
44+
month: 3,
45+
year: 2023,
46+
},
47+
};

animata/widget/calendar-widget.tsx

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import React, { useEffect, useRef, useState } from "react";
2+
import { AnimatePresence, motion } from "framer-motion";
3+
import { Calendar as CalendarIcon, DotIcon } from "lucide-react";
4+
5+
const monthArray = [
6+
"",
7+
"January",
8+
"February",
9+
"March",
10+
"April",
11+
"May",
12+
"June",
13+
"July",
14+
"August",
15+
"September",
16+
"October",
17+
"November",
18+
"December",
19+
];
20+
21+
interface EventType {
22+
date: number;
23+
title: string;
24+
time: string;
25+
}
26+
27+
export default function CalendarWidget({
28+
initialSelectedDate = 1,
29+
initialShowEvents = true,
30+
eventsData = [],
31+
month = 1,
32+
year = new Date().getFullYear(),
33+
}: {
34+
initialSelectedDate?: number;
35+
initialShowEvents?: boolean;
36+
eventsData?: EventType[];
37+
month?: number;
38+
year?: number;
39+
}) {
40+
const [selectedDate, setSelectedDate] = useState(initialSelectedDate);
41+
const [showEvents, setShowEvents] = useState(initialShowEvents);
42+
const scrollRef = useRef<HTMLDivElement>(null);
43+
44+
const dates = Array.from({ length: 30 }, (_, i) => i + 1);
45+
const daySymbols = ["S", "M", "T", "W", "T", "F", "S"];
46+
47+
const filteredEvents = eventsData.filter((event: EventType) => event.date === selectedDate);
48+
49+
useEffect(() => {
50+
if (scrollRef.current) {
51+
const selectedElement = scrollRef.current.querySelector(`[data-date="${selectedDate}"]`);
52+
if (selectedElement) {
53+
selectedElement.scrollIntoView({ behavior: "smooth", inline: "center", block: "nearest" });
54+
}
55+
}
56+
}, [selectedDate]);
57+
58+
return (
59+
<motion.div
60+
className="mx-auto max-w-sm rounded-3xl bg-slate-200 shadow-lg"
61+
initial={{ scale: 0.9, opacity: 0 }}
62+
animate={{ scale: 1, opacity: 1 }}
63+
transition={{ duration: 0.3 }}
64+
>
65+
<div className="mx-auto max-w-sm rounded-3xl px-6 py-2">
66+
<h2 className="mb-4 text-2xl font-bold">{`${monthArray[month]} ${year}`}</h2>
67+
<div
68+
ref={scrollRef}
69+
className="scrollbar-hide flex items-start space-x-2 overflow-x-auto py-2"
70+
style={{ scrollbarWidth: "none", msOverflowStyle: "none" }}
71+
>
72+
{dates.map((date, index) => (
73+
<motion.button
74+
key={date}
75+
data-date={date}
76+
className="flex w-10 flex-shrink-0 flex-col items-center justify-center gap-y-2 rounded-lg"
77+
onClick={() => {
78+
setSelectedDate(date);
79+
setShowEvents(true);
80+
}}
81+
whileHover={{ scale: 1.05 }}
82+
whileTap={{ scale: 0.95 }}
83+
>
84+
<span className="mb-1 text-xs">{daySymbols[(index + 4) % 7]}</span>
85+
<AnimatePresence>
86+
{selectedDate === date ? (
87+
<motion.span
88+
layoutId="highlighted-date"
89+
className="flex h-8 w-8 items-center justify-center rounded-full bg-gray-100 text-black shadow-lg"
90+
transition={{
91+
type: "spring",
92+
stiffness: 300,
93+
damping: 20,
94+
}}
95+
>
96+
{date}
97+
</motion.span>
98+
) : (
99+
<span className="flex h-8 w-8 items-center justify-center">{date}</span>
100+
)}
101+
</AnimatePresence>
102+
<span>
103+
{eventsData.find((alldates: EventType) => alldates.date === date) ? (
104+
<DotIcon />
105+
) : (
106+
""
107+
)}
108+
</span>
109+
</motion.button>
110+
))}
111+
</div>
112+
</div>
113+
114+
<div className="w-full rounded-3xl bg-[#fefefe] px-6 shadow-lg">
115+
<AnimatePresence mode="wait">
116+
{showEvents && (
117+
<motion.div
118+
key="events"
119+
className="scrollbar-hide mt-2 h-[150px] overflow-scroll border-t pt-4"
120+
initial={{ opacity: 0, y: 20 }}
121+
animate={{ opacity: 1, y: 0 }}
122+
exit={{ opacity: 0, y: -20 }}
123+
transition={{ duration: 0.2 }}
124+
>
125+
{filteredEvents.length > 0 ? (
126+
filteredEvents.map((event: EventType, index: number) => (
127+
<motion.div
128+
key={index}
129+
className="mb-2 border-b-2 border-slate-200"
130+
initial={{ opacity: 0, x: -20 }}
131+
animate={{ opacity: 1, x: 0 }}
132+
transition={{ delay: index * 0.1 }}
133+
>
134+
<h4 className="font-medium">{event.title}</h4>
135+
<p className="text-sm text-gray-500">{event.time}</p>
136+
</motion.div>
137+
))
138+
) : (
139+
<motion.div
140+
className="flex flex-col items-center text-gray-500"
141+
initial={{ opacity: 0 }}
142+
animate={{ opacity: 1 }}
143+
>
144+
<CalendarIcon className="mb-2 h-8 w-8" />
145+
<p>No Events</p>
146+
</motion.div>
147+
)}
148+
</motion.div>
149+
)}
150+
</AnimatePresence>
151+
</div>
152+
</motion.div>
153+
);
154+
}

content/docs/background/moving-gradient.mdx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ author: harimanok_
1515
```js
1616
theme: {
1717
extend: {
18+
animation: {
19+
"bg-position": "bg-position 3s infinite alternate",
20+
},
1821
keyframes: {
1922
"bg-position": {
2023
"0%": { backgroundPosition: "0% 50%" },

content/docs/container/marquee.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ theme: {
2424
from: { transform: "translateY(0)" },
2525
to: { transform: "translateY(calc(-100% - var(--gap)))" },
2626
},
27-
}
27+
},
2828
animation: {
2929
"marquee-horizontal": "marquee-x var(--duration) infinite linear",
3030
"marquee-vertical": "marquee-y var(--duration) linear infinite",

content/docs/section/pricing.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Pricing
3-
description: Pricing component that display the pricing options of various plans in an sleek and interactive way
3+
description: Pricing component that displays the pricing options of various plans in a sleek and interactive way
44
author: SatyamVyas04
55
---
66

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
title: Calendar Widget
3+
description: calendar widget is calender like widget with smooth animations and cool effects
4+
author: anshu_code
5+
---
6+
7+
<ComponentPreview name="widget-calendar-widget--docs" />
8+
9+
## Installation
10+
11+
<Steps>
12+
<Step>Install dependencies</Step>
13+
14+
```bash
15+
npm install framer-motion lucide-react
16+
```
17+
18+
<Step>Run the following command</Step>
19+
20+
It will create a new file `calendar-widget.tsx` inside the `components/animata/widget` directory.
21+
22+
```bash
23+
mkdir -p components/animata/widget && touch components/animata/widget/calendar-widget.tsx
24+
```
25+
26+
<Step>Paste the code</Step>{" "}
27+
28+
Open the newly created file and paste the following code:
29+
30+
```jsx file=<rootDir>/animata/widget/calendar-widget.tsx
31+
32+
```
33+
34+
</Steps>
35+
36+
## Credits
37+
38+
Built by [Anshuman](https://github.com/anshuman008)

hooks/use-newsletter-subscription.ts

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
"use client";
22
import { useState } from "react";
33

4-
const url = process.env.NEXT_PUBLIC_SUPABASE_URL + "/rest/v1/prelaunch_subscribers";
5-
const apiKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;
4+
const plunkApiUrl = "https://api.useplunk.com/v1/track";
5+
const plunkApiKey = process.env.NEXT_PUBLIC_PLUNK_API_KEY;
66

77
export default function useNewsletterSubscription() {
88
const initialState = {
@@ -29,20 +29,25 @@ export default function useNewsletterSubscription() {
2929
}
3030

3131
setState({ ...state, isLoading: true });
32-
const data = { email: state.email };
3332

34-
try {
35-
const response = await fetch(url, {
36-
method: "POST",
37-
// @ts-expect-error - Types for custom headers are not defined in fetch types
38-
headers: {
39-
apikey: apiKey,
40-
Authorization: "Bearer " + apiKey,
41-
"Content-Type": "application/json",
42-
Prefer: "return=minimal",
33+
const options = {
34+
method: "POST",
35+
headers: {
36+
"Content-Type": "application/json",
37+
Authorization: `Bearer ${plunkApiKey}`,
38+
},
39+
body: JSON.stringify({
40+
event: "newsletter_subscription",
41+
email: state.email,
42+
subscribed: true,
43+
data: {
44+
project_id: "animata",
4345
},
44-
body: JSON.stringify(data),
45-
});
46+
}),
47+
};
48+
49+
try {
50+
const response = await fetch(plunkApiUrl, options);
4651

4752
if (response.status >= 200 && response.status < 300) {
4853
// Email added successfully

yarn.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9414,8 +9414,8 @@ __metadata:
94149414
linkType: hard
94159415

94169416
"elliptic@npm:^6.5.3, elliptic@npm:^6.5.5":
9417-
version: 6.5.7
9418-
resolution: "elliptic@npm:6.5.7"
9417+
version: 6.6.1
9418+
resolution: "elliptic@npm:6.6.1"
94199419
dependencies:
94209420
bn.js: "npm:^4.11.9"
94219421
brorand: "npm:^1.1.0"
@@ -9424,7 +9424,7 @@ __metadata:
94249424
inherits: "npm:^2.0.4"
94259425
minimalistic-assert: "npm:^1.0.1"
94269426
minimalistic-crypto-utils: "npm:^1.0.1"
9427-
checksum: 10c0/799959b6c54ea3564e8961f35abdf8c77e37617f3051614b05ab1fb6a04ddb65bd1caa75ed1bae375b15dda312a0f79fed26ebe76ecf05c5a7af244152a601b8
9427+
checksum: 10c0/8b24ef782eec8b472053793ea1e91ae6bee41afffdfcb78a81c0a53b191e715cbe1292aa07165958a9bbe675bd0955142560b1a007ffce7d6c765bcaf951a867
94289428
languageName: node
94299429
linkType: hard
94309430

0 commit comments

Comments
 (0)