kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
feat(web): add sticky header
rodzic
2bca04d5a6
commit
85ac47783d
|
@ -0,0 +1,86 @@
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
import styles from './styles.module.css'
|
||||||
|
|
||||||
|
export default function AboutPage() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<section>
|
||||||
|
<h1>About</h1>
|
||||||
|
|
||||||
|
<div className={cn('prose dark:prose-invert', styles.markdown)}>
|
||||||
|
<h2>Our Mission</h2>
|
||||||
|
<p>
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
|
||||||
|
eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
||||||
|
<b>Ut enim ad minim veniam</b>, quis nostrud exercitation ullamco
|
||||||
|
laboris nisi ut aliquip ex ea commodo consequat.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Our Story</h2>
|
||||||
|
<p>
|
||||||
|
Duis aute irure dolor in reprehenderit in voluptate velit esse
|
||||||
|
cillum dolore eu fugiat nulla pariatur.
|
||||||
|
<em>Excepteur sint occaecat cupidatat non proident</em>, sunt in
|
||||||
|
culpa qui officia deserunt mollit anim id est laborum.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Our Values</h2>
|
||||||
|
<p>
|
||||||
|
Sed ut perspiciatis unde omnis iste natus error sit voluptatem
|
||||||
|
accusantium doloremque laudantium, totam rem aperiam, eaque ipsa
|
||||||
|
quae ab illo inventore veritatis et quasi architecto beatae vitae
|
||||||
|
dicta sunt explicabo.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Our Team</h2>
|
||||||
|
<p>
|
||||||
|
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut
|
||||||
|
fugit, sed quia consequuntur magni dolores eos qui ratione
|
||||||
|
voluptatem sequi nesciunt.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Our Technology</h2>
|
||||||
|
<p>
|
||||||
|
At vero eos et accusamus et iusto odio dignissimos ducimus qui
|
||||||
|
blanditiis praesentium voluptatum deleniti atque corrupti quos
|
||||||
|
dolores et quas molestias <b>excepturi sint occaecati</b> cupiditate
|
||||||
|
non provident.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Our Impact</h2>
|
||||||
|
<p>
|
||||||
|
Similique sunt in culpa qui officia deserunt mollitia animi, id est
|
||||||
|
laborum et dolorum fuga.
|
||||||
|
<em>Et harum quidem rerum facilis est et expedita distinctio</em>.
|
||||||
|
Nam libero tempore, cum soluta nobis est eligendi optio.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Our Future</h2>
|
||||||
|
<p>
|
||||||
|
Temporibus autem quibusdam et aut officiis debitis aut rerum
|
||||||
|
necessitatibus saepe eveniet ut et voluptates repudiandae sint et
|
||||||
|
molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente
|
||||||
|
delectus.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Our Community</h2>
|
||||||
|
<p>
|
||||||
|
Ut aut reiciendis voluptatibus maiores alias consequatur aut
|
||||||
|
perferendis doloribus asperiores repellat. Sed ut perspiciatis unde
|
||||||
|
omnis iste natus error sit voluptatem accusantium doloremque
|
||||||
|
laudantium.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Our Commitment</h2>
|
||||||
|
<p>
|
||||||
|
Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse
|
||||||
|
quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat
|
||||||
|
quo voluptas nulla pariatur?{' '}
|
||||||
|
<b>Excepteur sint occaecat cupidatat non proident</b>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,142 @@
|
||||||
|
.markdown {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
line-height: 1.6;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown > * {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 830px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown > *:first-child {
|
||||||
|
margin-top: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown img {
|
||||||
|
display: inline-block;
|
||||||
|
max-width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown a:not(:has(img)) {
|
||||||
|
display: inline-block;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: inherit;
|
||||||
|
line-height: 1.3;
|
||||||
|
position: relative;
|
||||||
|
transition: unset;
|
||||||
|
opacity: 1;
|
||||||
|
color: unset;
|
||||||
|
padding-bottom: 0.1rem;
|
||||||
|
border-color: var(--border);
|
||||||
|
border-bottom-width: 0.135rem;
|
||||||
|
background: transparent;
|
||||||
|
background-origin: border-box;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 50% 100%;
|
||||||
|
background-size: 0 0.135rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown a:hover:not(:has(img)),
|
||||||
|
.markdown a:focus:not(:has(img)) {
|
||||||
|
color: var(--tw-prose-links);
|
||||||
|
text-decoration: none;
|
||||||
|
border-bottom-color: transparent;
|
||||||
|
|
||||||
|
background-image: linear-gradient(90.68deg, #b439df 0.26%, #e5337e 102.37%);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 0 100%;
|
||||||
|
background-size: 100% 0.135rem;
|
||||||
|
|
||||||
|
transition-property: background-position, background-size;
|
||||||
|
transition-duration: 300ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown :where(ul):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown p + ul,
|
||||||
|
.markdown p + ol,
|
||||||
|
.markdown h1 + ul,
|
||||||
|
.markdown h2 + ul,
|
||||||
|
.markdown h3 + ul,
|
||||||
|
.markdown h4 + ul,
|
||||||
|
.markdown h5 + ul,
|
||||||
|
.markdown h6 + ul,
|
||||||
|
.markdown h1 + ol,
|
||||||
|
.markdown h2 + ol,
|
||||||
|
.markdown h3 + ol,
|
||||||
|
.markdown h4 + ol,
|
||||||
|
.markdown h5 + ol,
|
||||||
|
.markdown h6 + ol {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown p {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown li a {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown li:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown li:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h1,
|
||||||
|
.markdown h2,
|
||||||
|
.markdown h3,
|
||||||
|
.markdown h4,
|
||||||
|
.markdown h5,
|
||||||
|
.markdown h6 {
|
||||||
|
margin-top: 1.5em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h1 {
|
||||||
|
font-size: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h2 {
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h3 {
|
||||||
|
font-size: 1.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h4 {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h5 {
|
||||||
|
font-size: 1em;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h6 {
|
||||||
|
font-size: 1em;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 800px) {
|
||||||
|
.markdown img {
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,129 +0,0 @@
|
||||||
'use client'
|
|
||||||
|
|
||||||
import type {
|
|
||||||
PasswordChangeError,
|
|
||||||
PasswordChangeState
|
|
||||||
} from '@agentic/openauth/provider/password'
|
|
||||||
import { useState } from 'react'
|
|
||||||
|
|
||||||
import { authCopy } from '@/lib/auth-copy'
|
|
||||||
|
|
||||||
export default function ForgotPasswordPage() {
|
|
||||||
// TODO
|
|
||||||
const [error] = useState<PasswordChangeError | undefined>(undefined)
|
|
||||||
const [state] = useState<PasswordChangeState>({
|
|
||||||
type: 'start',
|
|
||||||
redirect: '/' // TODO
|
|
||||||
})
|
|
||||||
const [form] = useState<FormData | undefined>(undefined)
|
|
||||||
|
|
||||||
const passwordError = [
|
|
||||||
'invalid_password',
|
|
||||||
'password_mismatch',
|
|
||||||
'validation_error'
|
|
||||||
].includes(error?.type || '')
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<section>
|
|
||||||
<h1 className='my-0! text-center text-balance leading-snug md:leading-none'>
|
|
||||||
{authCopy.change_prompt}
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
<form data-component='form' method='post'>
|
|
||||||
{/* <FormAlert
|
|
||||||
message={
|
|
||||||
error?.type
|
|
||||||
? error.type === 'validation_error'
|
|
||||||
? (error.message ?? authCopy?.[`error_${error.type}`])
|
|
||||||
: authCopy?.[`error_${error.type}`]
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
/> */}
|
|
||||||
|
|
||||||
{state.type === 'start' && (
|
|
||||||
<>
|
|
||||||
<input type='hidden' name='action' value='code' />
|
|
||||||
|
|
||||||
<input
|
|
||||||
data-component='input'
|
|
||||||
autoFocus
|
|
||||||
type='email'
|
|
||||||
name='email'
|
|
||||||
required
|
|
||||||
value={form?.get('email')?.toString()}
|
|
||||||
placeholder={authCopy.input_email}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{state.type === 'code' && (
|
|
||||||
<>
|
|
||||||
<input type='hidden' name='action' value='verify' />
|
|
||||||
|
|
||||||
<input
|
|
||||||
data-component='input'
|
|
||||||
autoFocus
|
|
||||||
name='code'
|
|
||||||
minLength={6}
|
|
||||||
maxLength={6}
|
|
||||||
required
|
|
||||||
placeholder={authCopy.input_code}
|
|
||||||
autoComplete='one-time-code'
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{state.type === 'update' && (
|
|
||||||
<>
|
|
||||||
<input type='hidden' name='action' value='update' />
|
|
||||||
|
|
||||||
<input
|
|
||||||
data-component='input'
|
|
||||||
autoFocus
|
|
||||||
type='password'
|
|
||||||
name='password'
|
|
||||||
placeholder={authCopy.input_password}
|
|
||||||
required
|
|
||||||
value={!passwordError ? form?.get('password')?.toString() : ''}
|
|
||||||
autoComplete='new-password'
|
|
||||||
/>
|
|
||||||
|
|
||||||
<input
|
|
||||||
data-component='input'
|
|
||||||
type='password'
|
|
||||||
name='repeat'
|
|
||||||
required
|
|
||||||
value={!passwordError ? form?.get('password')?.toString() : ''}
|
|
||||||
placeholder={authCopy.input_repeat}
|
|
||||||
autoComplete='new-password'
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
<button data-component='button'>{authCopy.button_continue}</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
{state.type === 'code' && (
|
|
||||||
<form method='post'>
|
|
||||||
<input type='hidden' name='action' value='code' />
|
|
||||||
|
|
||||||
<input type='hidden' name='email' value={state.email} />
|
|
||||||
|
|
||||||
{state.type === 'code' && (
|
|
||||||
<div data-component='form-footer'>
|
|
||||||
<span>
|
|
||||||
{authCopy.code_return}{' '}
|
|
||||||
<a data-component='link' href='/login'>
|
|
||||||
{authCopy.login.toLowerCase()}
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<button data-component='link'>{authCopy.code_resend}</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</form>
|
|
||||||
)}
|
|
||||||
</section>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -135,7 +135,7 @@ body {
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
max-width: 100vw;
|
max-width: 100vw;
|
||||||
overflow-x: hidden;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
|
|
@ -107,13 +107,13 @@ export default function LoginPage() {
|
||||||
<div className='flex items-center'>
|
<div className='flex items-center'>
|
||||||
<Label htmlFor={field.name}>Password</Label>
|
<Label htmlFor={field.name}>Password</Label>
|
||||||
|
|
||||||
<a
|
{/* <a
|
||||||
href='/forgot-password'
|
href='/forgot-password'
|
||||||
className='ml-auto text-xs underline-offset-4 hover:underline'
|
className='ml-auto text-xs underline-offset-4 hover:underline'
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
>
|
>
|
||||||
Forgot your password?
|
Forgot your password?
|
||||||
</a>
|
</a> */}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Input
|
<Input
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
.root {
|
.root {
|
||||||
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
min-height: 100vh;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main {
|
.main {
|
||||||
|
|
|
@ -1,5 +1,18 @@
|
||||||
.header {
|
.header {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 200;
|
||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
max-width: 100vw;
|
||||||
|
overflow: hidden;
|
||||||
|
height: 55px;
|
||||||
|
min-height: 55px;
|
||||||
|
|
||||||
|
background: hsla(0, 0%, 100%, 0.8);
|
||||||
|
backdrop-filter: saturate(180%) blur(16px);
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -7,8 +20,20 @@
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:global(.dark) .header {
|
||||||
|
background: transparent;
|
||||||
|
box-shadow: inset 0 -1px 0 0 rgba(0, 0, 0, 0.1);
|
||||||
|
backdrop-filter: saturate(180%) blur(20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Workaround for Firefox not supporting backdrop-filter yet */
|
||||||
|
@-moz-document url-prefix() {
|
||||||
|
:global(.dark) .header {
|
||||||
|
background: hsla(203, 8%, 20%, 0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.headerContent {
|
.headerContent {
|
||||||
pointer-events: auto;
|
|
||||||
align-self: center;
|
align-self: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 1200px;
|
max-width: 1200px;
|
||||||
|
|
Ładowanie…
Reference in New Issue