mirror of
https://github.com/r-freeman/portfolio.git
synced 2024-11-22 18:35:40 +00:00
Subscription feature (WIP)
This commit is contained in:
parent
ba1a771296
commit
8ac2804674
@ -10,7 +10,7 @@ type VariantStyles = {
|
|||||||
type Button = {
|
type Button = {
|
||||||
variant?: string
|
variant?: string
|
||||||
className: string
|
className: string
|
||||||
href: string
|
href?: string
|
||||||
children: ReactNode
|
children: ReactNode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
28
components/Feature.tsx
Normal file
28
components/Feature.tsx
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import {ElementType, ReactNode} from 'react'
|
||||||
|
import {twMerge} from 'tailwind-merge'
|
||||||
|
|
||||||
|
type FeatureProps = {
|
||||||
|
icon: ElementType
|
||||||
|
title: String
|
||||||
|
children: ReactNode
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Feature({icon: Icon, title, children, className}: FeatureProps) {
|
||||||
|
return (
|
||||||
|
<div className={twMerge(`
|
||||||
|
rounded-2xl
|
||||||
|
border
|
||||||
|
border-zinc-100
|
||||||
|
p-6
|
||||||
|
dark:border-zinc-700/40
|
||||||
|
${className ?? ""}
|
||||||
|
`)}>
|
||||||
|
<h2 className="flex text-sm font-semibold text-zinc-900 dark:text-zinc-100">
|
||||||
|
<Icon className="h-6 w-6 flex-none"/>
|
||||||
|
<span className="ml-3">{title}</span>
|
||||||
|
</h2>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
import {BriefcaseIcon} from '@/components/icons/BriefcaseIcon'
|
import {BriefcaseIcon} from '@/components/icons/BriefcaseIcon'
|
||||||
import {ArrowDownIcon} from '@/components/icons/ArrowDownIcon'
|
import {ArrowDownIcon} from '@/components/icons/ArrowDownIcon'
|
||||||
import {Button} from '@/components/Button'
|
import {Button} from '@/components/Button'
|
||||||
|
import {Feature} from '@/components/Feature'
|
||||||
|
|
||||||
type Work = {
|
type Work = {
|
||||||
company: string
|
company: string
|
||||||
@ -44,15 +45,10 @@ export function Resume() {
|
|||||||
]
|
]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="rounded-2xl border border-zinc-100 p-6 dark:border-zinc-700/40">
|
<Feature icon={BriefcaseIcon} title="Work">
|
||||||
<h2 className="flex text-sm font-semibold text-zinc-900 dark:text-zinc-100">
|
|
||||||
<BriefcaseIcon className="h-6 w-6 flex-none"/>
|
|
||||||
<span className="ml-3">Work</span>
|
|
||||||
</h2>
|
|
||||||
<ol className="mt-6 space-y-4">
|
<ol className="mt-6 space-y-4">
|
||||||
{work.map((role, roleIndex) => (
|
{work.map((role, roleIndex) => (
|
||||||
<li key={roleIndex} className="flex gap-4">
|
<li key={roleIndex} className="flex gap-4">
|
||||||
|
|
||||||
<dl className="flex flex-auto flex-wrap gap-x-2">
|
<dl className="flex flex-auto flex-wrap gap-x-2">
|
||||||
<dt className="sr-only">Company</dt>
|
<dt className="sr-only">Company</dt>
|
||||||
<dd className="w-full flex-none text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
<dd className="w-full flex-none text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||||
@ -86,6 +82,6 @@ export function Resume() {
|
|||||||
<ArrowDownIcon
|
<ArrowDownIcon
|
||||||
className="h-4 w-4 stroke-zinc-400 transition group-active:stroke-zinc-600 dark:group-hover:stroke-zinc-50 dark:group-active:stroke-zinc-50"/>
|
className="h-4 w-4 stroke-zinc-400 transition group-active:stroke-zinc-600 dark:group-hover:stroke-zinc-50 dark:group-active:stroke-zinc-50"/>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</Feature>
|
||||||
)
|
)
|
||||||
}
|
}
|
25
components/Subscribe.tsx
Normal file
25
components/Subscribe.tsx
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import {Feature} from '@/components/Feature'
|
||||||
|
import {MailIcon} from '@/components/icons/MailIcon'
|
||||||
|
import {Button} from '@/components/Button'
|
||||||
|
|
||||||
|
export function Subscribe() {
|
||||||
|
return (
|
||||||
|
<Feature icon={MailIcon} title="Subscribe">
|
||||||
|
<p className="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
|
||||||
|
Get notified when I publish something new, and unsubscribe at any time.
|
||||||
|
</p>
|
||||||
|
<div className="mt-6 flex">
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
placeholder="Email address"
|
||||||
|
aria-label="Email address"
|
||||||
|
required
|
||||||
|
className="min-w-0 flex-auto appearance-none rounded-md border border-zinc-900/10 bg-white px-3 py-[calc(theme(spacing.2)-1px)] shadow-md shadow-zinc-800/5 placeholder:text-zinc-400 focus:border-indigo-500 focus:outline-none focus:ring-4 focus:ring-indigo-500/10 dark:border-zinc-700 dark:bg-zinc-700/[0.15] dark:text-zinc-200 dark:placeholder:text-zinc-500 dark:focus:border-indigo-400 dark:focus:ring-indigo-400/10 sm:text-sm"
|
||||||
|
/>
|
||||||
|
<Button className="ml-4 flex-none" variant="secondary">
|
||||||
|
Join
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Feature>
|
||||||
|
)
|
||||||
|
}
|
@ -2,11 +2,11 @@ import {Props} from '@/types'
|
|||||||
|
|
||||||
export function MailIcon(props: Props) {
|
export function MailIcon(props: Props) {
|
||||||
return (
|
return (
|
||||||
<svg viewBox="0 0 24 24" aria-hidden="true" {...props}>
|
<svg viewBox="0 0 24 24" fill="none" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"
|
||||||
<path
|
className="h-6 w-6 flex-none" {...props}>
|
||||||
fillRule="evenodd"
|
<path d="M2.75 7.75a3 3 0 0 1 3-3h12.5a3 3 0 0 1 3 3v8.5a3 3 0 0 1-3 3H5.75a3 3 0 0 1-3-3v-8.5Z"
|
||||||
d="M6 5a3 3 0 0 0-3 3v8a3 3 0 0 0 3 3h12a3 3 0 0 0 3-3V8a3 3 0 0 0-3-3H6Zm.245 2.187a.75.75 0 0 0-.99 1.126l6.25 5.5a.75.75 0 0 0 .99 0l6.25-5.5a.75.75 0 0 0-.99-1.126L12 12.251 6.245 7.187Z"
|
className="fill-zinc-100 stroke-zinc-400 dark:fill-zinc-100/10 dark:stroke-zinc-500"></path>
|
||||||
/>
|
<path d="m4 6 6.024 5.479a2.915 2.915 0 0 0 3.952 0L20 6" className="stroke-zinc-400 dark:stroke-zinc-500"></path>
|
||||||
</svg>
|
</svg>
|
||||||
)
|
)
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user