@rileybathurst/paddle 0.0.34 → 0.0.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +13 -4
- package/src/App.tsx +0 -1
- package/src/Button.tsx +15 -0
- package/src/PaddleBookNow.tsx +15 -0
- package/src/PaddleComposition.tsx +56 -0
- package/src/PaddleLocationCard.tsx +146 -0
- package/src/PaddleLocationDeck.tsx +21 -0
- package/src/PaddleSocials.tsx +44 -0
- package/src/PaddleTestimonials.tsx +24 -0
- package/src/PaddleTicket.tsx +53 -0
- package/src/PaddleTime.tsx +75 -0
- package/src/Test.tsx +3 -0
- package/src/assets/facebook-icon.tsx +26 -0
- package/src/assets/instagram-icon.tsx +27 -0
- package/src/assets/tripadvisor-icon.tsx +17 -0
- package/src/index.tsx +31 -1
- package/src/stories/BookNow.stories.tsx +19 -0
- package/src/stories/BookNow.tsx +29 -0
- package/src/stories/BrandList.stories.tsx +19 -0
- package/src/stories/BrandList.tsx +19 -0
- package/src/stories/Button.stories.tsx +19 -0
- package/src/stories/Button.tsx +15 -35
- package/src/stories/Card.stories.tsx +19 -0
- package/src/stories/Card.tsx +43 -0
- package/src/stories/Colors.mdx +71 -0
- package/src/stories/Composition.stories.tsx +19 -0
- package/src/stories/Composition.tsx +21 -0
- package/src/stories/Deal.tsx +31 -0
- package/src/stories/Deck.stories.tsx +19 -0
- package/src/stories/Deck.tsx +22 -0
- package/src/stories/Eyebrow.stories.tsx +19 -0
- package/src/stories/Eyebrow.tsx +21 -0
- package/src/stories/Footer.stories.tsx +19 -0
- package/src/stories/Footer.tsx +94 -0
- package/src/stories/Header.stories.ts +7 -7
- package/src/stories/Header.tsx +23 -51
- package/src/stories/Language.stories.tsx +19 -0
- package/src/stories/Language.tsx +22 -0
- package/src/stories/Links.stories.tsx +19 -0
- package/src/stories/Links.tsx +25 -0
- package/src/stories/Location.stories.tsx +19 -0
- package/src/stories/Location.tsx +55 -0
- package/src/stories/LocationDeck.stories.tsx +19 -0
- package/src/stories/LocationDeck.tsx +42 -0
- package/src/stories/Logo.stories.tsx +19 -0
- package/src/stories/Logo.tsx +60 -0
- package/src/stories/Page.stories.ts +6 -15
- package/src/stories/Page.tsx +116 -63
- package/src/stories/Pricing.stories.tsx +19 -0
- package/src/stories/Pricing.tsx +74 -0
- package/src/stories/Socials.stories.tsx +19 -0
- package/src/stories/Socials.tsx +50 -0
- package/src/stories/Spec.stories.tsx +19 -0
- package/src/stories/Spec.tsx +99 -0
- package/src/stories/Svg.stories.tsx +19 -0
- package/src/stories/Svg.tsx +23 -0
- package/src/stories/Testimonial.stories.tsx +19 -0
- package/src/stories/Testimonial.tsx +24 -0
- package/src/stories/Testimonials.stories.tsx +19 -0
- package/src/stories/Testimonials.tsx +42 -0
- package/src/stories/Ticket.stories.tsx +19 -0
- package/src/stories/Ticket.tsx +47 -0
- package/src/stories/TopBar.stories.tsx +19 -0
- package/src/stories/TopBar.tsx +19 -0
- package/src/stories/Typography.mdx +51 -0
- package/src/stories/Typography.stories.tsx +19 -0
- package/src/stories/Typography.tsx +39 -0
- package/src/stories/Widths.stories.tsx +19 -0
- package/src/stories/Widths.tsx +151 -0
- package/src/styles/a11y.css +10 -0
- package/src/styles/app.css +9 -1
- package/src/styles/body.css +0 -9
- package/src/styles/buttons.css +41 -0
- package/src/styles/color.css +21 -0
- package/src/styles/layout.css +156 -0
- package/src/styles/links.css +23 -0
- package/src/styles/lists.css +17 -0
- package/src/styles/media.css +139 -0
- package/src/styles/typography.css +229 -0
- package/src/styles/variables.css +140 -0
- package/src/testimonial-fragment.tsx +11 -0
- package/src/types/location-card-types.ts +24 -0
- package/src/types/ticket-types.ts +19 -0
- package/.eslintrc.cjs +0 -14
- package/.storybook/main.ts +0 -20
- package/.storybook/preview.ts +0 -16
- package/index.html +0 -13
- package/public/vite.svg +0 -1
- package/src/App.css +0 -42
- package/src/stories/Button.stories.ts +0 -52
- package/src/stories/button.css +0 -30
- package/src/test.tsx +0 -11
- package/tsconfig.json +0 -25
- package/tsconfig.node.json +0 -11
- package/vite.config.ts +0 -7
package/README.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
# Paddle
|
|
1
|
+
# Paddle
|
package/package.json
CHANGED
|
@@ -1,22 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rileybathurst/paddle",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.37",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "vite",
|
|
8
8
|
"build": "tsc && vite build",
|
|
9
9
|
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
|
10
10
|
"preview": "vite preview",
|
|
11
|
-
"
|
|
11
|
+
"start": "storybook dev -p 6006",
|
|
12
12
|
"build-storybook": "storybook build"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
+
"color-cards": "^1.0.14",
|
|
16
|
+
"gatsby": "^5.13.6",
|
|
17
|
+
"gatsby-plugin-image": "^3.13.1",
|
|
15
18
|
"react": "^18.2.0",
|
|
16
|
-
"react-
|
|
19
|
+
"react-aria-components": "^1.2.1",
|
|
20
|
+
"react-dom": "^18.2.0",
|
|
21
|
+
"react-markdown": "^9.0.1"
|
|
17
22
|
},
|
|
18
23
|
"devDependencies": {
|
|
19
24
|
"@chromatic-com/storybook": "^1.3.4",
|
|
25
|
+
"@faker-js/faker": "^8.4.1",
|
|
20
26
|
"@storybook/addon-essentials": "^8.0.10",
|
|
21
27
|
"@storybook/addon-interactions": "^8.0.10",
|
|
22
28
|
"@storybook/addon-links": "^8.0.10",
|
|
@@ -42,5 +48,8 @@
|
|
|
42
48
|
"main": "src/index.tsx",
|
|
43
49
|
"module": "src/index.tsx",
|
|
44
50
|
"author": "",
|
|
45
|
-
"license": "ISC"
|
|
51
|
+
"license": "ISC",
|
|
52
|
+
"files": [
|
|
53
|
+
"src/*"
|
|
54
|
+
]
|
|
46
55
|
}
|
package/src/App.tsx
CHANGED
package/src/Button.tsx
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
|
|
3
|
+
interface ButtonTypes {
|
|
4
|
+
peek_base: string
|
|
5
|
+
strapiLocaleName: string
|
|
6
|
+
}
|
|
7
|
+
export const Button = ({ peek_base, strapiLocaleName }: ButtonTypes) =>
|
|
8
|
+
<a
|
|
9
|
+
href={peek_base}
|
|
10
|
+
rel="noopener noreferrer"
|
|
11
|
+
className="book-now"
|
|
12
|
+
title={`Book now with ${strapiLocaleName} kayak and paddleboard`}
|
|
13
|
+
>
|
|
14
|
+
BOOK NOW
|
|
15
|
+
</a>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
|
|
3
|
+
interface BookNowTypes {
|
|
4
|
+
peek_base: string
|
|
5
|
+
strapiLocaleName: string
|
|
6
|
+
}
|
|
7
|
+
export const PaddleBookNow = ({ peek_base, strapiLocaleName }: BookNowTypes) =>
|
|
8
|
+
<a
|
|
9
|
+
href={peek_base}
|
|
10
|
+
rel="noopener noreferrer"
|
|
11
|
+
className="book-now"
|
|
12
|
+
title={`Book now with ${strapiLocaleName} kayak and paddleboard`}
|
|
13
|
+
>
|
|
14
|
+
BOOK NOW
|
|
15
|
+
</a>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
// ! this isnt finished it wont have faker when its done
|
|
3
|
+
import { faker } from '@faker-js/faker';
|
|
4
|
+
// import { GatsbyImage } from "gatsby-plugin-image"
|
|
5
|
+
|
|
6
|
+
// import WaterTexture from "../images/watertexture";
|
|
7
|
+
// import Kayaker from "../images/kayaker";
|
|
8
|
+
// import Supper from "../images/supper";
|
|
9
|
+
// import { useStrapiTextures } from "../hooks/use-strapi-textures"
|
|
10
|
+
|
|
11
|
+
/* // TODO: rename
|
|
12
|
+
interface TopThreeTypes {
|
|
13
|
+
className: string;
|
|
14
|
+
}
|
|
15
|
+
function TopThree({ className }: TopThreeTypes) {
|
|
16
|
+
|
|
17
|
+
// const { query } = useStrapiTextures()
|
|
18
|
+
// console.log(query.baseone);
|
|
19
|
+
|
|
20
|
+
return <GatsbyImage
|
|
21
|
+
image={useStrapiTextures().topthree.image.localFile.childImageSharp.gatsbyImageData}
|
|
22
|
+
alt="deepwater texture"
|
|
23
|
+
className={`texture-slice crops ${props.className}`}
|
|
24
|
+
objectFit="contain"
|
|
25
|
+
/>
|
|
26
|
+
|
|
27
|
+
// ! Testing
|
|
28
|
+
return null;
|
|
29
|
+
} */
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
interface CompositionTypes {
|
|
33
|
+
sport?: string;
|
|
34
|
+
}
|
|
35
|
+
const PaddleComposition = ({ sport }: CompositionTypes) => {
|
|
36
|
+
return (
|
|
37
|
+
<div className="composition">
|
|
38
|
+
{/* <WaterTexture className="texture-1" /> */}
|
|
39
|
+
<img
|
|
40
|
+
src={faker.image.urlPlaceholder()}
|
|
41
|
+
alt={faker.location.city()}
|
|
42
|
+
className="texture-1"
|
|
43
|
+
/>
|
|
44
|
+
<img
|
|
45
|
+
src={faker.image.urlPlaceholder()}
|
|
46
|
+
alt={faker.location.city()}
|
|
47
|
+
className="texture-2 img-wrapped"
|
|
48
|
+
/>
|
|
49
|
+
{/* <TopThree className="texture-2 img__wrapped" /> */}
|
|
50
|
+
{/* {sport === 'paddleboard' ? <Supper className="paddler" /> : <Kayaker className="paddler" />} */}
|
|
51
|
+
{faker.datatype.boolean() ? <>Supper</> : <>Kayaker</>}
|
|
52
|
+
</div >
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export default PaddleComposition
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// TODO: Season is super broken
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { Link } from 'gatsby';
|
|
5
|
+
import Markdown from "react-markdown";
|
|
6
|
+
import type { LocationCardTypes } from "./types/location-card-types";
|
|
7
|
+
|
|
8
|
+
interface SeasonTypes {
|
|
9
|
+
season_start: string;
|
|
10
|
+
season_end: string;
|
|
11
|
+
opening_time: string;
|
|
12
|
+
closing_time: string;
|
|
13
|
+
name: string;
|
|
14
|
+
}
|
|
15
|
+
function Season({ season_start, season_end, opening_time, closing_time, name }: SeasonTypes) {
|
|
16
|
+
|
|
17
|
+
// TODO: these need a query but thats not the most important first step
|
|
18
|
+
if (name === "Free Parking Lot" || name === "Parking" || name === "Delivery") {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// console.log(opening_time);
|
|
23
|
+
|
|
24
|
+
/* if (new Date(season_start) < new Date()) {
|
|
25
|
+
return (
|
|
26
|
+
<p>
|
|
27
|
+
{opening_time ? "Open Daily: " : null}
|
|
28
|
+
<HourMin time={opening_time} />
|
|
29
|
+
{opening_time ? " - : " : null}
|
|
30
|
+
<HourMin time={closing_time} />
|
|
31
|
+
</p>
|
|
32
|
+
)
|
|
33
|
+
} */
|
|
34
|
+
|
|
35
|
+
/* return (
|
|
36
|
+
<p>
|
|
37
|
+
We're closed for the season:<br />
|
|
38
|
+
We will reopen<br />
|
|
39
|
+
{season_start} - {season_end}<br />
|
|
40
|
+
Weather Permitting
|
|
41
|
+
</p>
|
|
42
|
+
) */
|
|
43
|
+
return (
|
|
44
|
+
<p>
|
|
45
|
+
{/* {opening_time ? "Open Daily: " : null} */}
|
|
46
|
+
Open Daily 9:30am - 5:30pm<br />
|
|
47
|
+
Weather Permitting
|
|
48
|
+
{/* <HourMin time={opening_time} /> */}
|
|
49
|
+
{/* {opening_time ? " - : " : null} */}
|
|
50
|
+
{/* <HourMin time={closing_time} /> */}
|
|
51
|
+
</p>
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
interface ContentTypes {
|
|
56
|
+
svg: string;
|
|
57
|
+
name: string;
|
|
58
|
+
address: {
|
|
59
|
+
data: {
|
|
60
|
+
address: string;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
description: {
|
|
64
|
+
data: {
|
|
65
|
+
description: string;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
opening_time: string;
|
|
69
|
+
closing_time: string;
|
|
70
|
+
|
|
71
|
+
locale: {
|
|
72
|
+
season_start: string;
|
|
73
|
+
season_end: string;
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function Content({ svg, name, address, description, opening_time, closing_time, locale }: ContentTypes) {
|
|
77
|
+
return (
|
|
78
|
+
<>
|
|
79
|
+
<div
|
|
80
|
+
className="svg"
|
|
81
|
+
dangerouslySetInnerHTML={{ __html: svg }}
|
|
82
|
+
/>
|
|
83
|
+
|
|
84
|
+
<div>
|
|
85
|
+
<h3 className="elbrus">{name}</h3>
|
|
86
|
+
<Markdown className="react-markdown">
|
|
87
|
+
{address.data.address}
|
|
88
|
+
</Markdown>
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
<div>
|
|
92
|
+
<Season
|
|
93
|
+
season_start={locale.season_start}
|
|
94
|
+
season_end={locale.season_end}
|
|
95
|
+
opening_time={opening_time}
|
|
96
|
+
closing_time={closing_time}
|
|
97
|
+
name={name}
|
|
98
|
+
/>
|
|
99
|
+
<br />
|
|
100
|
+
<Markdown className="react-markdown" >
|
|
101
|
+
{description.data.description}
|
|
102
|
+
</Markdown>
|
|
103
|
+
{/* // TODO: add phone but dont break the link on link rule {name === "On Water Rental" ? <Phone /> : null} */}
|
|
104
|
+
</div>
|
|
105
|
+
</>
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function PaddleLocationCard({ svg, name, link, address, description, opening_time, closing_time, locale, background }: LocationCardTypes) {
|
|
110
|
+
if (link.includes('http')) {
|
|
111
|
+
return (
|
|
112
|
+
<a href={link}
|
|
113
|
+
className={`location ${background}`}
|
|
114
|
+
target="_blank"
|
|
115
|
+
rel="noopener noreferrer"
|
|
116
|
+
title={name}
|
|
117
|
+
>
|
|
118
|
+
<Content
|
|
119
|
+
svg={svg}
|
|
120
|
+
name={name}
|
|
121
|
+
address={address}
|
|
122
|
+
description={description}
|
|
123
|
+
opening_time={opening_time}
|
|
124
|
+
closing_time={closing_time}
|
|
125
|
+
locale={locale}
|
|
126
|
+
/>
|
|
127
|
+
</a>
|
|
128
|
+
)
|
|
129
|
+
}
|
|
130
|
+
return (
|
|
131
|
+
<Link
|
|
132
|
+
to={`/${link}`}
|
|
133
|
+
className={`location ${background}`}
|
|
134
|
+
>
|
|
135
|
+
<Content
|
|
136
|
+
svg={svg}
|
|
137
|
+
name={name}
|
|
138
|
+
address={address}
|
|
139
|
+
description={description}
|
|
140
|
+
opening_time={opening_time}
|
|
141
|
+
closing_time={closing_time}
|
|
142
|
+
locale={locale}
|
|
143
|
+
/>
|
|
144
|
+
</Link>
|
|
145
|
+
)
|
|
146
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { PaddleLocationCard } from "./PaddleLocationCard";
|
|
3
|
+
import type { LocationCardTypes } from "./types/location-card-types";
|
|
4
|
+
|
|
5
|
+
interface LocationDeckTypes {
|
|
6
|
+
background?: string;
|
|
7
|
+
nodes: LocationCardTypes[];
|
|
8
|
+
}
|
|
9
|
+
export function PaddleLocationDeck({ nodes, background }: LocationDeckTypes) {
|
|
10
|
+
return (
|
|
11
|
+
<section className="location-deck">
|
|
12
|
+
{nodes.map((location: LocationCardTypes) => (
|
|
13
|
+
<PaddleLocationCard
|
|
14
|
+
key={location.id}
|
|
15
|
+
{...location}
|
|
16
|
+
background={background}
|
|
17
|
+
/>
|
|
18
|
+
))}
|
|
19
|
+
</section>
|
|
20
|
+
)
|
|
21
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
|
|
3
|
+
import FacebookIcon from "./assets/facebook-icon"
|
|
4
|
+
import InstagramIcon from "./assets/instagram-icon"
|
|
5
|
+
import TripAdvisorIcon from "./assets/tripadvisor-icon"
|
|
6
|
+
|
|
7
|
+
interface SocialsTypes {
|
|
8
|
+
instagram: string
|
|
9
|
+
facebook: string
|
|
10
|
+
tripadvisor: string
|
|
11
|
+
}
|
|
12
|
+
export const PaddleSocials = ({ instagram, facebook, tripadvisor }: SocialsTypes) =>
|
|
13
|
+
<div className="social">
|
|
14
|
+
{facebook ?
|
|
15
|
+
<a
|
|
16
|
+
href={facebook}
|
|
17
|
+
target='_blank' rel='noopener noreferrer'
|
|
18
|
+
aria-label='facebook link'
|
|
19
|
+
>
|
|
20
|
+
<FacebookIcon />
|
|
21
|
+
</a>
|
|
22
|
+
: null
|
|
23
|
+
}
|
|
24
|
+
{instagram ?
|
|
25
|
+
<a href={instagram}
|
|
26
|
+
target='_blank'
|
|
27
|
+
rel='noopener noreferrer'
|
|
28
|
+
aria-label='instagram link'
|
|
29
|
+
>
|
|
30
|
+
<InstagramIcon />
|
|
31
|
+
</a>
|
|
32
|
+
: null
|
|
33
|
+
}
|
|
34
|
+
{tripadvisor ?
|
|
35
|
+
<a href={tripadvisor}
|
|
36
|
+
target='_blank'
|
|
37
|
+
rel='noopener noreferrer'
|
|
38
|
+
aria-label='tripadvisor link'
|
|
39
|
+
>
|
|
40
|
+
<TripAdvisorIcon />
|
|
41
|
+
</a>
|
|
42
|
+
: null
|
|
43
|
+
}
|
|
44
|
+
</div>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
|
|
3
|
+
interface TestimonialsTypes {
|
|
4
|
+
nodes: {
|
|
5
|
+
id: string;
|
|
6
|
+
testimonial: string;
|
|
7
|
+
sign: string;
|
|
8
|
+
customer: string;
|
|
9
|
+
location: string;
|
|
10
|
+
}[];
|
|
11
|
+
}
|
|
12
|
+
export function PaddleTestimonials({ nodes }: TestimonialsTypes) {
|
|
13
|
+
return (
|
|
14
|
+
<ul className='testimonials condor'>
|
|
15
|
+
{nodes.map((testimonial) => (
|
|
16
|
+
<li key={testimonial.id}>
|
|
17
|
+
<p className='elbrus'><span className='denali font-serif'>“</span>{testimonial.testimonial}<span className='denali font-serif'>”</span></p>
|
|
18
|
+
<p>{testimonial.sign} {testimonial.customer}</p>
|
|
19
|
+
<p className='kosciuszko'>{testimonial.location}</p>
|
|
20
|
+
</li>
|
|
21
|
+
))}
|
|
22
|
+
</ul>
|
|
23
|
+
)
|
|
24
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { Link } from "gatsby"
|
|
3
|
+
import { GatsbyImage } from "gatsby-plugin-image"
|
|
4
|
+
import type { TicketTypes } from "./types/ticket-types"
|
|
5
|
+
import { PaddleTime } from "./PaddleTime"
|
|
6
|
+
|
|
7
|
+
export function PaddleTicket({ ogimage, slug, name, start, finish, duration, timeframe, fitness, excerpt, price, peek }: TicketTypes) {
|
|
8
|
+
|
|
9
|
+
const time = PaddleTime({
|
|
10
|
+
start: start,
|
|
11
|
+
finish: finish,
|
|
12
|
+
duration: duration,
|
|
13
|
+
timeframe: timeframe,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<section className="ticket">
|
|
18
|
+
<Link to={`/tours/${slug}`}>
|
|
19
|
+
<GatsbyImage
|
|
20
|
+
image={ogimage?.localFile?.childImageSharp?.gatsbyImageData}
|
|
21
|
+
alt={`${ogimage?.alternativeText || name} image`}
|
|
22
|
+
objectFit="cover"
|
|
23
|
+
className="card__image"
|
|
24
|
+
/>
|
|
25
|
+
</Link>
|
|
26
|
+
<h4 className="card__title">
|
|
27
|
+
<Link to={`/tours/${slug}`}>
|
|
28
|
+
{name}
|
|
29
|
+
</Link>
|
|
30
|
+
</h4>
|
|
31
|
+
<div className="card__specs">
|
|
32
|
+
<h4>{time.entry}</h4>
|
|
33
|
+
{/* // TODO: I'd like a spec backup here */}
|
|
34
|
+
{fitness ? <h4 className="capitalize">{fitness} <span>Fitness</span></h4> : null}
|
|
35
|
+
</div>
|
|
36
|
+
<hr />
|
|
37
|
+
<p>{excerpt}</p>
|
|
38
|
+
<hr />
|
|
39
|
+
<div className="card__details">
|
|
40
|
+
<h5>${price}</h5>
|
|
41
|
+
<a
|
|
42
|
+
href={peek}
|
|
43
|
+
target="_blank"
|
|
44
|
+
rel="noopener noreferrer"
|
|
45
|
+
className="book-now"
|
|
46
|
+
>
|
|
47
|
+
BOOK NOW
|
|
48
|
+
</a>
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
</section>
|
|
52
|
+
)
|
|
53
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// import * as React from "react"
|
|
2
|
+
|
|
3
|
+
interface TimeTypes {
|
|
4
|
+
start?: string | null;
|
|
5
|
+
finish?: string | null;
|
|
6
|
+
duration?: number | null;
|
|
7
|
+
timeframe?: string | null;
|
|
8
|
+
}
|
|
9
|
+
export const PaddleTime = ({ start, finish, duration, timeframe }: TimeTypes) => {
|
|
10
|
+
|
|
11
|
+
// TODO: sunset is a whole thing
|
|
12
|
+
|
|
13
|
+
const hairSpace = String.fromCharCode(0x200A);
|
|
14
|
+
|
|
15
|
+
if (timeframe) {
|
|
16
|
+
return {
|
|
17
|
+
// key: timeframe, cant return key its a react special prop
|
|
18
|
+
// https://react.dev/warnings/special-props
|
|
19
|
+
entry: timeframe,
|
|
20
|
+
value: 'timeframe'
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (start && finish) {
|
|
25
|
+
|
|
26
|
+
const startHours = start.split(':')[0];
|
|
27
|
+
let startHoursInt: number = Number.parseInt(startHours);
|
|
28
|
+
const startMins = start.split(':')[1];
|
|
29
|
+
const startMinsInt: number = Number.parseInt(startMins);
|
|
30
|
+
const startAmpm = startHoursInt >= 12 ? 'pm' : 'am';
|
|
31
|
+
|
|
32
|
+
if (startHoursInt > 12) {
|
|
33
|
+
startHoursInt = startHoursInt - 12;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const finishHours = finish.split(':')[0];
|
|
37
|
+
let finishHoursInt: number = Number.parseInt(finishHours);
|
|
38
|
+
const finishMins = finish.split(':')[1];
|
|
39
|
+
const finishMinsInt: number = Number.parseInt(finishMins);
|
|
40
|
+
const finishAmpm = finishHoursInt >= 12 ? 'pm' : 'am';
|
|
41
|
+
|
|
42
|
+
if (finishHoursInt > 12) {
|
|
43
|
+
finishHoursInt = finishHoursInt - 12;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
entry: startHours === '12' ? 'noon' : `${startHoursInt}${startMinsInt > 0 ? `:${startMinsInt}${hairSpace}` : ''}${startAmpm}
|
|
48
|
+
-
|
|
49
|
+
${finishHours === '12' ? 'noon' : `${finishHoursInt}${finishMinsInt > 0 ? `:${finishMinsInt}${hairSpace}` : ''}${hairSpace}${finishAmpm}`}`,
|
|
50
|
+
value: "time"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (duration) {
|
|
55
|
+
if (duration > 90) {
|
|
56
|
+
const hours = Math.floor(duration / 60);
|
|
57
|
+
const mins = duration % 60;
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
entry: `${hours}${hairSpace}hrs ${mins > 0 ? `${mins}${hairSpace}mins` : ''} `,
|
|
61
|
+
value: "duration"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
entry: `${duration}${hairSpace} mins`,
|
|
67
|
+
value: "duration"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
entry: null,
|
|
73
|
+
value: null
|
|
74
|
+
}
|
|
75
|
+
}
|
package/src/Test.tsx
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
const FacebookIcon = () => {
|
|
4
|
+
return (
|
|
5
|
+
<svg
|
|
6
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
7
|
+
viewBox="0 0 1024 1024"
|
|
8
|
+
className="facebook"
|
|
9
|
+
>
|
|
10
|
+
<title>facebook page</title>
|
|
11
|
+
<g>
|
|
12
|
+
<path
|
|
13
|
+
className="circle"
|
|
14
|
+
d="M1024,512C1024,229.2,794.8,0,512,0S0,229.2,0,512c0,255.6,187.2,467.4,432,505.8V660H302V512h130V399.2
|
|
15
|
+
C432,270.9,508.4,200,625.4,200c56,0,114.6,10,114.6,10v126h-64.6c-63.6,0-83.4,39.5-83.4,80v96h142l-22.7,148H592v357.8
|
|
16
|
+
C836.8,979.4,1024,767.6,1024,512z"/>
|
|
17
|
+
<path
|
|
18
|
+
className="f"
|
|
19
|
+
d="M711.3,660L734,512H592v-96c0-40.5,19.8-80,83.4-80H740V210c0,0-58.6-10-114.6-10
|
|
20
|
+
c-117,0-193.4,70.9-193.4,199.2V512H302v148h130v357.8c26.1,4.1,52.8,6.2,80,6.2s53.9-2.1,80-6.2V660H711.3z"/>
|
|
21
|
+
</g>
|
|
22
|
+
</svg>
|
|
23
|
+
);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default FacebookIcon;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
// I got this from the instagram website rather than the brand book as that one was a mess
|
|
4
|
+
const InstagramIcon = () => {
|
|
5
|
+
return (
|
|
6
|
+
<svg
|
|
7
|
+
viewBox="0 0 80 81"
|
|
8
|
+
fill="url(#jsc_s_2)"
|
|
9
|
+
className="instagram"
|
|
10
|
+
>
|
|
11
|
+
<title>instagram logo</title>
|
|
12
|
+
<defs>
|
|
13
|
+
<linearGradient x1="69.27%" x2="128.20%" y1="129.46%" y2="29.46%" id="jsc_s_2">
|
|
14
|
+
<stop offset="0" stopColor="#FDD074" />
|
|
15
|
+
<stop offset="25%" stopColor="#F77F34" />
|
|
16
|
+
<stop offset="50%" stopColor="#DD326E" />
|
|
17
|
+
<stop offset="75%" stopColor="#D82B7E" />
|
|
18
|
+
<stop offset="100%" stopColor="#A432B1" />
|
|
19
|
+
</linearGradient>
|
|
20
|
+
</defs>
|
|
21
|
+
<path d="m43.655 0 5.21.025 3.4.055 2.74.095L56.49.24c4.26.195 7.165.87 9.71 1.86 2.63 1.025 4.86 2.39 7.085 4.615 2.225 2.225 3.595 4.46 4.615 7.09.88 2.26 1.51 4.81 1.775 8.34l.19 3.775.09 3.59.045 6.855-.03 12.835-.075 4.015-.135 3.3c-.195 4.26-.87 7.17-1.86 9.715-1.02 2.63-2.39 4.865-4.615 7.09-2.225 2.225-4.455 3.59-7.085 4.615-2.26.88-4.81 1.51-8.335 1.775l-4.3.205-3.78.085-6.13.035-12.835-.03-4.01-.075-3.3-.135c-4.26-.195-7.165-.87-9.71-1.86-2.63-1.025-4.865-2.39-7.085-4.615C4.49 71.095 3.12 68.86 2.1 66.23 1.22 63.97.59 61.42.325 57.89l-.15-2.86-.095-2.745-.055-3.395L0 42.545l.025-11.4.055-3.395.095-2.745.065-1.485c.195-4.26.87-7.17 1.86-9.715 1.02-2.63 2.39-4.865 4.615-7.09C8.935 4.49 11.17 3.125 13.8 2.1c2.26-.88 4.81-1.51 8.34-1.775l2.855-.15 2.74-.095 3.4-.055L36.345 0h7.31zm5.09 7.235h-17.49l-3.03.045-4.39.165a32.326 32.326 0 0 0-3.294.307l-.599.097a20.85 20.85 0 0 0-1.316.273l-.46.117c-.148.04-.29.08-.426.121l-.93.31-.4.15c-1.87.73-3.2 1.595-4.6 2.995-1.4 1.4-2.265 2.735-2.99 4.6l-.31.845-.136.432c-.362 1.201-.705 2.817-.874 5.133l-.09 1.7-.13 3.57-.065 6.18.015 14.255.08 4.41.13 3.25a31.47 31.47 0 0 0 .344 3.534l.098.57c.017.092.034.182.052.27l.108.511.113.474c.019.076.038.151.058.224l.117.424.12.393.06.185.31.845c.725 1.865 1.59 3.2 2.99 4.6 1.4 1.4 2.73 2.27 4.6 2.995l.845.305.378.121.2.06.423.118c.073.02.148.04.224.058l.473.113.51.108.55.102c1.044.18 2.296.32 3.822.39l4.875.175 6.515.055 14.115-.025 3.58-.07 3.245-.135c1.526-.07 2.778-.21 3.822-.39l.55-.102.51-.108.473-.113.224-.058.423-.118.393-.12.185-.061.845-.305c1.87-.725 3.2-1.595 4.6-2.995 1.4-1.4 2.265-2.735 2.995-4.6l.305-.845c.41-1.24.82-2.96 1.01-5.565l.19-4.245.08-4.285.02-6.18-.02-11.145-.08-4.285-.13-3.225a33.046 33.046 0 0 0-.262-2.977l-.093-.622c-.049-.3-.1-.582-.155-.85l-.112-.516a18.598 18.598 0 0 0-.116-.479l-.12-.442-.062-.209-.38-1.135-.075-.2c-.73-1.865-1.595-3.2-2.995-4.6-1.4-1.4-2.73-2.265-4.6-2.995l-.4-.15-.93-.31-.229-.066-.488-.13c-1.102-.279-2.505-.525-4.358-.659L54.21 7.36l-2.435-.08-3.03-.045z" />
|
|
22
|
+
<path d="M40 19.47c11.345 0 20.54 9.2 20.54 20.545 0 11.35-9.195 20.55-20.54 20.55-11.345 0-20.54-9.2-20.54-20.55C19.46 28.67 28.655 19.47 40 19.47zm0 7.21c-7.365 0-13.335 5.97-13.335 13.335 0 7.37 5.97 13.34 13.335 13.34 7.365 0 13.335-5.97 13.335-13.34 0-7.365-5.97-13.335-13.335-13.335zM66.15 18.65a4.801 4.801 0 1 1-9.598-.002 4.801 4.801 0 0 1 9.598.002z" />
|
|
23
|
+
</svg>
|
|
24
|
+
);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export default InstagramIcon;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
const TripadvisorIcon = () => {
|
|
4
|
+
return (
|
|
5
|
+
<svg
|
|
6
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
7
|
+
viewBox="0 0 696.6 696.6"
|
|
8
|
+
className="tripadvisor"
|
|
9
|
+
>
|
|
10
|
+
<title>tripadvisor logo</title>
|
|
11
|
+
<circle cx="348.3" cy="348.3" r="348.3" />
|
|
12
|
+
<path d="M563.4,280.3l42-45.8h-93.2c-98.8-67.3-228.8-67.3-327.6,0h-93.4l42,45.8c-52.2,48-55.7,129.3-7.6,181.6,48,52.2,129.3,55.7,181.6,7.6l41.2,44.8,41.2-44.8c52.1,48.2,133.4,44.9,181.6-7.2,48.2-52.1,44.9-133.4-7.2-181.6-.2-.1-.3-.3-.5-.4ZM219.8,462.2c-48,0-87-39-87-87s39-87,87-87,87,39,87,87h0c0,48-39,87-87,87ZM348.3,372.8c0-57.2-41.6-106.3-96.5-127.3,61.8-25.7,131.2-25.7,193,0-54.8,21-96.5,70.1-96.5,127.3h0ZM476.8,462.2c-48,0-87-39-87-87s39-87,87-87,87,39,87,87h0c0,48-39,87-87,87ZM476.8,329.7c-25.2,0-45.6,20.4-45.6,45.6s20.4,45.6,45.6,45.6,45.6-20.4,45.6-45.6h0c0-25.2-20.4-45.6-45.6-45.6h0ZM265.4,375.2c0,25.2-20.4,45.6-45.5,45.6-25.2,0-45.6-20.4-45.6-45.5,0-25.2,20.4-45.6,45.5-45.6s45.6,20.4,45.6,45.5h0Z" />
|
|
13
|
+
</svg>
|
|
14
|
+
);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default TripadvisorIcon;
|
package/src/index.tsx
CHANGED
|
@@ -1 +1,31 @@
|
|
|
1
|
-
|
|
1
|
+
// eslint-disable-next-line react-refresh/only-export-components
|
|
2
|
+
|
|
3
|
+
// TODO: these dont work
|
|
4
|
+
// Fragments
|
|
5
|
+
// export * from "./testimonial-fragment";
|
|
6
|
+
|
|
7
|
+
// Atoms
|
|
8
|
+
export * from "./PaddleBookNow";
|
|
9
|
+
export * from "./PaddleTime";
|
|
10
|
+
|
|
11
|
+
// Molecules
|
|
12
|
+
export * from "./PaddleComposition";
|
|
13
|
+
export * from "./PaddleSocials";
|
|
14
|
+
export * from "./PaddleLocationCard";
|
|
15
|
+
export * from "./PaddleTestimonials";
|
|
16
|
+
export * from "./PaddleTicket";
|
|
17
|
+
|
|
18
|
+
// Organisms
|
|
19
|
+
export * from "./PaddleLocationDeck";
|
|
20
|
+
|
|
21
|
+
// Test a function
|
|
22
|
+
export * from "./PaddleTestimonials";
|
|
23
|
+
|
|
24
|
+
// Templates
|
|
25
|
+
|
|
26
|
+
// Pages
|
|
27
|
+
|
|
28
|
+
// TODO: test
|
|
29
|
+
// Types
|
|
30
|
+
export * from "./types/ticket-types";
|
|
31
|
+
export * from "./types/location-card-types";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// this is the Name.stories.tsx file
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
+
import { fn } from '@storybook/test';
|
|
4
|
+
import { BookNow } from './BookNow';
|
|
5
|
+
|
|
6
|
+
const meta = {
|
|
7
|
+
component: BookNow,
|
|
8
|
+
title: 'Atoms/BookNow',
|
|
9
|
+
args: { onClick: fn() },
|
|
10
|
+
} satisfies Meta<typeof BookNow>;
|
|
11
|
+
|
|
12
|
+
export default meta;
|
|
13
|
+
type Story = StoryObj<typeof meta>;
|
|
14
|
+
|
|
15
|
+
export const Primary: Story = {
|
|
16
|
+
args: {
|
|
17
|
+
primary: true,
|
|
18
|
+
},
|
|
19
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// this is the Name.tsx file
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { faker } from '@faker-js/faker';
|
|
4
|
+
|
|
5
|
+
interface BookNowProps {
|
|
6
|
+
primary?: boolean;
|
|
7
|
+
onClick?: () => void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const BookNow = ({
|
|
11
|
+
primary = false,
|
|
12
|
+
...props
|
|
13
|
+
}: BookNowProps) => {
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<main
|
|
17
|
+
{...props}
|
|
18
|
+
>
|
|
19
|
+
<a
|
|
20
|
+
href={faker.location.city()}
|
|
21
|
+
rel="noopener noreferrer"
|
|
22
|
+
className="book-now"
|
|
23
|
+
title={`Book now with ${faker.location.city()} kayak and paddleboard`}
|
|
24
|
+
>
|
|
25
|
+
BOOK NOW
|
|
26
|
+
</a>
|
|
27
|
+
</main>
|
|
28
|
+
);
|
|
29
|
+
};
|