Styling adjustmnets, fix pages feature, replace styles with tw

pull/150/head
Max Leiter 3 years ago
parent 817852a472
commit dcf9c99969

@ -32,6 +32,6 @@ const nextConfig = {
}
}
export default bundleAnalyzer({ enabled: process.env.ANALYZE === "true" })(
export default process.env.ANALYZE === "true" ? bundleAnalyzer({ enabled: true })(
nextConfig
)
) : nextConfig

@ -15,7 +15,7 @@
"dependencies": {
"@next-auth/prisma-adapter": "^1.0.7",
"@next/eslint-plugin-next": "13.4.9",
"@prisma/client": "^4.16.2",
"@prisma/client": "^5.0.0",
"@radix-ui/react-alert-dialog": "^1.0.4",
"@radix-ui/react-dialog": "^1.0.3",
"@radix-ui/react-dropdown-menu": "^2.0.4",
@ -25,6 +25,7 @@
"@radix-ui/react-tabs": "^1.0.3",
"@radix-ui/react-tooltip": "^1.0.5",
"@tailwindcss/nesting": "0.0.0-insiders.565cd3e",
"@tailwindcss/typography": "^0.5.9",
"class-variance-authority": "^0.6.0",
"client-only": "^0.0.1",
"client-zip": "2.3.1",
@ -84,7 +85,7 @@
"postcss-preset-env": "^8.4.1",
"prettier": "2.8.7",
"prettier-plugin-tailwindcss": "^0.3.0",
"prisma": "^4.16.2",
"prisma": "^5.0.0",
"tailwindcss": "^3.3.2",
"typescript": "5.1.6",
"typescript-plugin-css-modules": "5.0.1"

@ -7,13 +7,13 @@ settings:
dependencies:
'@next-auth/prisma-adapter':
specifier: ^1.0.7
version: 1.0.7(@prisma/client@4.16.2)(next-auth@4.22.1)
version: 1.0.7(@prisma/client@5.0.0)(next-auth@4.22.1)
'@next/eslint-plugin-next':
specifier: 13.4.9
version: 13.4.9
'@prisma/client':
specifier: ^4.16.2
version: 4.16.2(prisma@4.16.2)
specifier: ^5.0.0
version: 5.0.0(prisma@5.0.0)
'@radix-ui/react-alert-dialog':
specifier: ^1.0.4
version: 1.0.4(@types/react-dom@18.0.11)(@types/react@18.0.35)(react-dom@18.2.0)(react@18.2.0)
@ -41,6 +41,9 @@ dependencies:
'@tailwindcss/nesting':
specifier: 0.0.0-insiders.565cd3e
version: 0.0.0-insiders.565cd3e(postcss@8.4.21)
'@tailwindcss/typography':
specifier: ^0.5.9
version: 0.5.9(tailwindcss@3.3.2)
class-variance-authority:
specifier: ^0.6.0
version: 0.6.0(typescript@5.1.6)
@ -220,8 +223,8 @@ devDependencies:
specifier: ^0.3.0
version: 0.3.0(prettier@2.8.7)
prisma:
specifier: ^4.16.2
version: 4.16.2
specifier: ^5.0.0
version: 5.0.0
tailwindcss:
specifier: ^3.3.2
version: 3.3.2
@ -1240,13 +1243,13 @@ packages:
'@jridgewell/resolve-uri': 3.1.0
'@jridgewell/sourcemap-codec': 1.4.14
/@next-auth/prisma-adapter@1.0.7(@prisma/client@4.16.2)(next-auth@4.22.1):
/@next-auth/prisma-adapter@1.0.7(@prisma/client@5.0.0)(next-auth@4.22.1):
resolution: {integrity: sha512-Cdko4KfcmKjsyHFrWwZ//lfLUbcLqlyFqjd/nYE2m3aZ7tjMNUjpks47iw7NTCnXf+5UWz5Ypyt1dSs1EP5QJw==}
peerDependencies:
'@prisma/client': '>=2.26.0 || >=3'
next-auth: ^4
dependencies:
'@prisma/client': 4.16.2(prisma@4.16.2)
'@prisma/client': 5.0.0(prisma@5.0.0)
next-auth: 4.22.1(next@13.4.9)(react-dom@18.2.0)(react@18.2.0)
dev: false
@ -1395,9 +1398,9 @@ packages:
resolution: {integrity: sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw==}
dev: false
/@prisma/client@4.16.2(prisma@4.16.2):
resolution: {integrity: sha512-qCoEyxv1ZrQ4bKy39GnylE8Zq31IRmm8bNhNbZx7bF2cU5aiCCnSa93J2imF88MBjn7J9eUQneNxUQVJdl/rPQ==}
engines: {node: '>=14.17'}
/@prisma/client@5.0.0(prisma@5.0.0):
resolution: {integrity: sha512-XlO5ELNAQ7rV4cXIDJUNBEgdLwX3pjtt9Q/RHqDpGf43szpNJx2hJnggfFs7TKNx0cOFsl6KJCSfqr5duEU/bQ==}
engines: {node: '>=16.13'}
requiresBuild: true
peerDependencies:
prisma: '*'
@ -1405,16 +1408,16 @@ packages:
prisma:
optional: true
dependencies:
'@prisma/engines-version': 4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81
prisma: 4.16.2
'@prisma/engines-version': 4.17.0-26.6b0aef69b7cdfc787f822ecd7cdc76d5f1991584
prisma: 5.0.0
dev: false
/@prisma/engines-version@4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81:
resolution: {integrity: sha512-q617EUWfRIDTriWADZ4YiWRZXCa/WuhNgLTVd+HqWLffjMSPzyM5uOWoauX91wvQClSKZU4pzI4JJLQ9Kl62Qg==}
/@prisma/engines-version@4.17.0-26.6b0aef69b7cdfc787f822ecd7cdc76d5f1991584:
resolution: {integrity: sha512-HHiUF6NixsldsP3JROq07TYBLEjXFKr6PdH8H4gK/XAoTmIplOJBCgrIUMrsRAnEuGyRoRLXKXWUb943+PFoKQ==}
dev: false
/@prisma/engines@4.16.2:
resolution: {integrity: sha512-vx1nxVvN4QeT/cepQce68deh/Turxy5Mr+4L4zClFuK1GlxN3+ivxfuv+ej/gvidWn1cE1uAhW7ALLNlYbRUAw==}
/@prisma/engines@5.0.0:
resolution: {integrity: sha512-kyT/8fd0OpWmhAU5YnY7eP31brW1q1YrTGoblWrhQJDiN/1K+Z8S1kylcmtjqx5wsUGcP1HBWutayA/jtyt+sg==}
requiresBuild: true
/@radix-ui/primitive@1.0.0:
@ -2390,6 +2393,18 @@ packages:
postcss-nested: 5.0.6(postcss@8.4.21)
dev: false
/@tailwindcss/typography@0.5.9(tailwindcss@3.3.2):
resolution: {integrity: sha512-t8Sg3DyynFysV9f4JDOVISGsjazNb48AeIYQwcL+Bsq5uf4RYL75C1giZ43KISjeDGBaTN3Kxh7Xj/vRSMJUUg==}
peerDependencies:
tailwindcss: '>=3.0.0 || insiders'
dependencies:
lodash.castarray: 4.4.0
lodash.isplainobject: 4.0.6
lodash.merge: 4.6.2
postcss-selector-parser: 6.0.10
tailwindcss: 3.3.2
dev: false
/@total-typescript/ts-reset@0.4.2:
resolution: {integrity: sha512-vqd7ZUDSrXFVT1n8b2kc3LnklncDQFPvR58yUS1kEP23/nHPAO9l1lMjUfnPrXYYk4Hj54rrLKMW5ipwk7k09A==}
dev: true
@ -5774,17 +5789,24 @@ packages:
resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==}
dev: true
/lodash.castarray@4.4.0:
resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==}
dev: false
/lodash.debounce@4.0.8:
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
dev: false
/lodash.isplainobject@4.0.6:
resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
dev: false
/lodash.memoize@4.1.2:
resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==}
dev: false
/lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
dev: true
/lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
@ -7283,6 +7305,14 @@ packages:
postcss-selector-parser: 6.0.11
dev: true
/postcss-selector-parser@6.0.10:
resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==}
engines: {node: '>=4'}
dependencies:
cssesc: 3.0.0
util-deprecate: 1.0.2
dev: false
/postcss-selector-parser@6.0.11:
resolution: {integrity: sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==}
engines: {node: '>=4'}
@ -7503,13 +7533,13 @@ packages:
parse-ms: 2.1.0
dev: true
/prisma@4.16.2:
resolution: {integrity: sha512-SYCsBvDf0/7XSJyf2cHTLjLeTLVXYfqp7pG5eEVafFLeT0u/hLFz/9W196nDRGUOo1JfPatAEb+uEnTQImQC1g==}
engines: {node: '>=14.17'}
/prisma@5.0.0:
resolution: {integrity: sha512-KYWk83Fhi1FH59jSpavAYTt2eoMVW9YKgu8ci0kuUnt6Dup5Qy47pcB4/TLmiPAbhGrxxSz7gsSnJcCmkyPANA==}
engines: {node: '>=16.13'}
hasBin: true
requiresBuild: true
dependencies:
'@prisma/engines': 4.16.2
'@prisma/engines': 5.0.0
/process-nextick-args@2.0.1:
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}

@ -12,8 +12,6 @@ import { useRouter } from "next/navigation"
import Note from "@components/note"
import { ErrorQueryParamsHandler } from "./query-handler"
import { AuthProviders } from "@lib/server/auth-props"
import { TypographyH1 } from "@components/typography"
import { cn } from "@lib/cn"
function Auth({
page,

@ -4,7 +4,7 @@ import { useToasts } from "@components/toasts"
import { useSearchParams } from "next/navigation"
import { Suspense, useEffect } from "react"
function _ErrorQueryParamsHandler() {
function InnerErrorQueryParamsHandler() {
const queryParams = useSearchParams()
const { setToast } = useToasts()
@ -24,7 +24,7 @@ export function ErrorQueryParamsHandler() {
/* Suspense boundary because useSearchParams causes static bailout */
return (
<Suspense fallback={null}>
<_ErrorQueryParamsHandler />
<InnerErrorQueryParamsHandler />
</Suspense>
)
}

@ -1,7 +1,13 @@
"use client"
import FormattingIcons from "src/app/(drift)/(posts)/new/components/edit-document-list/edit-document/formatting-icons"
import { ChangeEvent, ClipboardEvent, ComponentProps, useRef } from "react"
import {
ChangeEvent,
ClipboardEvent,
ComponentProps,
useRef,
useState
} from "react"
import TextareaMarkdown, { TextareaMarkdownRef } from "textarea-markdown-editor"
import Preview, { StaticPreview } from "../preview"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@components/tabs"
@ -28,13 +34,16 @@ export default function DocumentTabs({
...props
}: Props) {
const codeEditorRef = useRef<TextareaMarkdownRef>(null)
const [activeTab, setActiveTab] = useState<"preview" | "edit">(defaultTab)
const handleTabChange = (newTab: string) => {
if (newTab === "preview") {
codeEditorRef.current?.focus()
}
setActiveTab(newTab as "preview" | "edit")
}
const formattingIconsVisibilityClass =
activeTab === "preview" ? "hidden" : "block"
return (
<Tabs {...props} onValueChange={handleTabChange} defaultValue={defaultTab}>
<TabsList className="flex justify-between">
@ -44,7 +53,12 @@ export default function DocumentTabs({
{isEditing ? "Preview" : "Rendered"}
</TabsTrigger>
</div>
{isEditing && <FormattingIcons textareaRef={codeEditorRef} className="ml-auto" />}
{isEditing && (
<FormattingIcons
textareaRef={codeEditorRef}
className={`ml-auto ${formattingIconsVisibilityClass}`}
/>
)}
</TabsList>
<TabsContent value="edit">
<div

@ -23,19 +23,6 @@
margin: 0;
}
.content .listItem {
}
.content li .fileIcon {
display: inline-block;
margin-right: var(--gap-half);
}
.content li .fileTitle {
font-size: calc(0.875 * 16px);
}
.content li::before {
content: "";
padding: 0;

@ -6,7 +6,6 @@ import { ChevronDown, Code, File as FileIcon } from "react-feather"
import { Spinner } from "@components/spinner"
import Link from "next/link"
import { buttonVariants } from "@components/button"
import { cn } from "@lib/cn"
function FileDropdown({
files,
@ -36,18 +35,18 @@ function FileDropdown({
if (codeFileExtensions.includes(extension || "")) {
return {
...file,
icon: <Code />
icon: <Code className="w-4 h-4"/>
}
} else {
return {
...file,
icon: <FileIcon />
icon: <FileIcon className="w-4 h-4"/>
}
}
})
const content = (
<ul>
<ul className="text-sm">
{items.map((item) => (
<li key={item.id} className="flex">
<Link

@ -19,6 +19,11 @@
padding: var(--gap-half);
}
/* first element should never have a top margin */
.markdownPreview > *:first-child {
margin-top: 0;
}
.markdownPreview h1,
.markdownPreview h2,
.markdownPreview h3,
@ -26,52 +31,26 @@
.markdownPreview h5,
.markdownPreview h6 {
font-weight: 600;
letter-spacing: -0.025em;
margin-top: 1.5rem;
margin-bottom: 0.5rem;
}
.markdownPreview h1 {
font-size: 1.65rem;
line-height: 2.5rem;
@media (min-width: 1024px) {
font-size: 3rem;
line-height: 1;
}
font-size: 1.775rem;
}
.markdownPreview h2 {
padding-bottom: 0.5rem;
font-size: 1.875rem;
line-height: 2.25rem;
font-weight: 600;
border-bottom-width: 1px;
@media (min-width: 1024px) {
font-size: 2.25rem;
line-height: 1;
}
font-size: 1.5rem;
}
.markdownPreview h3 {
font-size: 1.5rem;
line-height: 2rem;
@media (min-width: 1024px) {
font-size: 1.75rem;
line-height: 1;
}
font-size: 1.25rem;
}
.markdownPreview h4 {
font-size: 1.25rem;
line-height: 1.8rem;
font-size: 1.125rem;
}
.markdownPreview h5 {
font-size: 1.125rem;
line-height: 1.75rem;
font-size: 1.1rem;
}
.markdownPreview p {

@ -3,7 +3,6 @@
import { useRouter } from "next/navigation"
import { useCallback, useState, ClipboardEvent } from "react"
import generateUUID from "@lib/generate-uuid"
import styles from "./post.module.css"
import EditDocumentList from "./edit-document-list"
import { ChangeEvent } from "react"
import getTitleForPostCopy from "src/app/lib/get-title-for-post-copy"
@ -13,7 +12,6 @@ import PasswordModal from "../../../../components/password-modal"
import Title from "./title"
import FileDropzone from "./drag-and-drop"
import { Button, buttonVariants } from "@components/button"
import { Input } from "@components/input"
import { useToasts } from "@components/toasts"
import { fetchWithUser } from "src/app/lib/fetch-with-user"
import dynamic from "next/dynamic"
@ -36,7 +34,7 @@ const DatePicker = dynamic(
)}
>
<CalendarIcon className="w-4 h-4 mr-2" />
<span>Won't expire</span>
<span>Won&apos;t expire</span>
</Button>
)
}
@ -66,7 +64,9 @@ function Post({
const [title, setTitle] = useState(
getTitleForPostCopy(initialPost?.title) || ""
)
const [description, setDescription] = useState(initialPost?.description || "")
const [description /*, setDescription */] = useState(
initialPost?.description || ""
)
const [expiresAt, setExpiresAt] = useState<Date>()
const defaultDocs: Document[] = initialPost
@ -149,7 +149,7 @@ function Post({
if (!docs.length) {
setToast({
message: "Please add at least one document",
message: "Please add at least one file",
type: "error"
})
hasErrored = true
@ -188,13 +188,13 @@ function Post({
setTitle(e.target.value)
}, [])
const onChangeDescription = useCallback(
(e: ChangeEvent<HTMLInputElement>) => {
e.preventDefault()
setDescription(e.target.value)
},
[]
)
// const onChangeDescription = useCallback(
// (e: ChangeEvent<HTMLInputElement>) => {
// e.preventDefault()
// setDescription(e.target.value)
// },
// []
// )
function onClosePasswordModal() {
setPasswordModalVisible(false)
@ -205,10 +205,6 @@ function Post({
return onSubmit("protected", password)
}
function onChangeExpiration(date: Date) {
return setExpiresAt(date)
}
function updateDocTitle(i: number) {
return (title: string) => {
setDocs((docs) =>
@ -259,8 +255,8 @@ function Post({
}
return (
<div className={styles.root}>
<Title title={title} onChange={onChangeTitle} />
<div className="flex flex-col flex-1 gap-4">
<Title title={title} onChange={onChangeTitle} className="py-4" />
{/* <Description description={description} onChange={onChangeDescription} /> */}
<EditDocumentList
onPaste={onPaste}
@ -335,30 +331,30 @@ function Post({
export default Post
function CustomTimeInput({
date,
value,
onChange
}: {
date: Date
value: string
onChange: (date: string) => void
}) {
return (
<input
type="time"
value={value}
onChange={(e) => {
if (!isNaN(date.getTime())) {
onChange(e.target.value || date.toISOString().slice(11, 16))
}
}}
style={{
backgroundColor: "var(--bg)",
border: "1px solid var(--light-gray)",
borderRadius: "var(--radius)"
}}
required
/>
)
}
// function CustomTimeInput({
// date,
// value,
// onChange
// }: {
// date: Date
// value: string
// onChange: (date: string) => void
// }) {
// return (
// <input
// type="time"
// value={value}
// onChange={(e) => {
// if (!isNaN(date.getTime())) {
// onChange(e.target.value || date.toISOString().slice(11, 16))
// }
// }}
// style={{
// backgroundColor: "var(--bg)",
// border: "1px solid var(--light-gray)",
// borderRadius: "var(--radius)"
// }}
// required
// />
// )
// }

@ -17,11 +17,12 @@ const placeholder = titlePlaceholders[3]
type props = {
onChange: (e: ChangeEvent<HTMLInputElement>) => void
title?: string
className?: string
}
function Title({ onChange, title }: props) {
function Title({ onChange, title, className}: props) {
return (
<div className="pt-4">
<div className={className}>
<Input
placeholder={placeholder}
value={title}

@ -3,7 +3,6 @@
import { Button } from "@components/button"
import ButtonGroup from "@components/button-group"
import FileDropdown from "src/app/(drift)/(posts)/components/file-dropdown"
import { Edit, ArrowUpCircle, Archive } from "react-feather"
import styles from "./post-buttons.module.css"
import { useRouter } from "next/navigation"
import { PostWithFiles } from "@lib/server/prisma"

@ -73,7 +73,7 @@ async function PublicPostList() {
id: true,
title: true,
content: true,
html: true,
html: true
}
},
authorId: true

@ -9,7 +9,6 @@ import { useEffect, useState } from "react"
import styles from "./profile.module.css"
import useSWR from "swr"
import { User } from "@prisma/client"
import { Spinner } from "@components/spinner"
function Profile() {
const { session } = useSessionSWR()

@ -13,7 +13,7 @@ const badgeVariants = cva(
"bg-secondary hover:bg-secondary/80 border-transparent text-secondary-foreground",
destructive:
"bg-destructive hover:bg-destructive/80 border-transparent text-destructive-foreground",
outline: "text-foreground"
outline: "text-foreground",
}
},
defaultVariants: {

@ -36,7 +36,6 @@ const ExpirationBadge = ({
}
}, [expirationDate])
console.log("expirationDate", expirationDate, timeUntilString)
if (!expirationDate) {
return null
}
@ -44,7 +43,7 @@ const ExpirationBadge = ({
const isExpired = expirationDate < new Date()
return (
<Badge variant={isExpired ? "destructive" : "default"}>
<Badge variant={isExpired ? "destructive" : "outline"}>
<Tooltip
content={`${expirationDate.toLocaleDateString()} ${expirationDate.toLocaleTimeString()}`}
>

@ -5,7 +5,6 @@ import { useCallback, useState } from "react"
import ButtonGroup from "@components/button-group"
import { Button } from "@components/button"
import { useToasts } from "@components/toasts"
import { Spinner } from "@components/spinner"
import { useRouter } from "next/navigation"
import { useSessionSWR } from "@lib/use-session-swr"
import { fetchWithUser } from "src/app/lib/fetch-with-user"

@ -6,11 +6,11 @@ import { cn } from "@lib/cn"
import { Spinner } from "@components/spinner"
const buttonVariants = cva(
"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background",
"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-75 disabled:pointer-events-none ring-offset-background",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
default: "bg-primary/80 text-primary-foreground/80 hover:bg-primary/70",
destructive:
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline:

@ -27,7 +27,7 @@ export function DatePicker({
)}
>
<CalendarIcon className="w-4 h-4 mr-2" />
{expiresAt ? format(expiresAt, "PPP") : <span>Won't expire</span>}
{expiresAt ? format(expiresAt, "PPP") : <span>Won&apos;t expire</span>}
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0">

@ -4,10 +4,9 @@ import Link from "next/link"
import { cn } from "@lib/cn"
import { useSessionSWR } from "@lib/use-session-swr"
import { PropsWithChildren, useEffect, useState } from "react"
import { PropsWithChildren } from "react"
import { useSelectedLayoutSegments } from "next/navigation"
import Image from "next/image"
import FadeIn from "@components/fade-in"
import { useTheme } from "next-themes"
// <NavButton

@ -1,5 +1,4 @@
import NextLink from "next/link"
import styles from "./link.module.css"
import { cn } from "@lib/cn"
type LinkProps = {

@ -1,7 +1,6 @@
import { Button } from "@components/button"
import { Input } from "@components/input"
import Note from "@components/note"
import { useState } from "react"
import { MouseEventHandler, useState } from "react"
import styles from "./modal.module.css"
import {
AlertDialog,
@ -31,7 +30,7 @@ const PasswordModal = ({
const [confirmPassword, setConfirmPassword] = useState<string>("")
const [error, setError] = useState<string>()
const onSubmit: React.FormEventHandler<HTMLFormElement> = (e) => {
const onSubmit: MouseEventHandler<HTMLButtonElement> = (e) => {
e.preventDefault()
if (!password || (creating && !confirmPassword)) {
setError("Please enter a password")

@ -2,11 +2,9 @@ import VisibilityBadge from "../badges/visibility-badge"
import FadeIn from "@components/fade-in"
import ExpirationBadge from "@components/badges/expiration-badge"
import CreatedAgoBadge from "@components/badges/created-ago-badge"
import { useRouter } from "next/navigation"
import styles from "./list-item.module.css"
import Link from "@components/link"
import type { PostWithFiles } from "@lib/server/prisma"
import { Tooltip } from "@components/tooltip"
import { Badge } from "@components/badges/badge"
import {
Card,
@ -15,25 +13,8 @@ import {
CardHeader,
CardTitle
} from "@components/card"
import { Button } from "@components/button"
import {
ArrowUpCircle,
Code,
Database,
Edit,
FileText,
MoreVertical,
Terminal,
Trash
} from "react-feather"
import { codeFileExtensions } from "@lib/constants"
import {
DropdownMenu,
DropdownMenuItem,
DropdownMenuTrigger
} from "@components/dropdown-menu"
import { DropdownMenuContent } from "@radix-ui/react-dropdown-menu"
import DocumentTabs from "src/app/(drift)/(posts)/components/document-tabs"
import { useEffect, useRef, useState } from "react"
// TODO: isOwner should default to false so this can be used generically
const HomeListItem = ({
@ -44,30 +25,23 @@ const HomeListItem = ({
deletePost: () => void
hideActions?: boolean
}) => {
const router = useRouter()
const [isExpanded, setIsExpanded] = useState(false)
const [isOverflowing, setIsOverflowing] = useState(false)
const containerRef = useRef<HTMLDivElement>(null)
const getIconFromFilename = (filename: string) => {
const extension = filename.split(".").pop()
switch (extension) {
case "sql":
return <Database />
case "sh":
case "fish":
case "bash":
case "zsh":
case ".zshrc":
case ".bashrc":
case ".bash_profile":
return <Terminal />
default:
if (codeFileExtensions.includes(extension || "")) {
return <Code />
} else {
return <FileText />
}
}
const handleExpandClick = () => {
setIsExpanded(!isExpanded)
}
useEffect(() => {
console.log("checking overflow", containerRef.current)
if (!containerRef.current) return
if (containerRef.current.scrollHeight > containerRef.current.clientHeight) {
console.log("overflowing")
setIsOverflowing(true)
}
}, [post])
return (
<FadeIn key={post.id} as="li">
<Card>
@ -102,13 +76,31 @@ const HomeListItem = ({
)}
</CardHeader>
<CardContent>
<DocumentTabs
isEditing={false}
staticPreview={post.files[0].html}
defaultTab={"preview"}
<div
className={`overflow-y-hidden ${
isExpanded ? "max-h-full" : "max-h-64"
}`}
ref={containerRef}
>
{post.files[0].content}
</DocumentTabs>
<DocumentTabs
isEditing={false}
staticPreview={post.files[0].html}
defaultTab={"preview"}
>
{post.files[0].content}
</DocumentTabs>
</div>
{isOverflowing && (
<div className="flex items-center mt-2">
<hr className="flex-grow border-gray-300 dark:border-gray-700" />
<div className="inline-block px-2 border border-gray-300 rounded text-accent-foreground dark:border-gray-700">
<button onClick={handleExpandClick} className="text-sm font-bold transition-colors hover:bg-gray-100 dark:hover:bg-gray-800">
{isExpanded ? "Collapse" : "Expand"}
</button>
</div>
<hr className="flex-grow border-gray-300 dark:border-gray-700" />
</div>
)}
</CardContent>
</Card>
</FadeIn>

@ -43,7 +43,6 @@ const PostList = ({
const showSkeleton = skeleton || searching
console.log(initialPosts)
// eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: address this
const onSearch = useCallback(
debounce((query: string) => {
@ -88,7 +87,10 @@ const PostList = ({
})
if (!res?.ok) {
console.error(res)
setToast({
message: "Failed to delete post",
type: "error"
})
return
} else {
setPosts((posts) => posts?.filter((post) => post.id !== postId))

@ -6,7 +6,6 @@ import { useRouter } from "next/navigation"
import styles from "./list-item.module.css"
import Link from "@components/link"
import type { PostWithFiles } from "@lib/server/prisma"
import { Tooltip } from "@components/tooltip"
import { Badge } from "@components/badges/badge"
import {
Card,
@ -15,7 +14,6 @@ import {
CardHeader,
CardTitle
} from "@components/card"
import { Button } from "@components/button"
import {
ArrowUpCircle,
Code,

@ -28,13 +28,14 @@ export default async function FilePage({
}
return (
<>
<h1 style={{ color: "var(--gray)" }}>{file.title}</h1>
<hr />
<main className="max-w-3xl px-4 mx-auto dark:prose-invert dark:bg-gray-800">
<h1 className="prose-2xl text-foreground ">{file.title}</h1>
<hr className="my-4 border-foreground" />
<article
dangerouslySetInnerHTML={{ __html: file.html.toString("utf-8") }}
className="prose dark:prose-dark"
/>
</>
</main>
)
}

@ -7,7 +7,7 @@ export default function ThemeProvider({
children
}: PropsWithChildren<unknown>) {
return (
<NextThemesProvider enableSystem defaultTheme="dark">
<NextThemesProvider enableSystem defaultTheme="dark" attribute="class" enableColorScheme>
{children}
</NextThemesProvider>
)

@ -55,7 +55,7 @@
color-scheme: dark;
--background: 0 0% 100%;
--foreground: 222.2 47.4% 11.2%;
--foreground: #fafbfc;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;

@ -72,5 +72,5 @@ module.exports = {
},
},
},
plugins: [require("tailwindcss-animate")],
plugins: [require("tailwindcss-animate"), require('@tailwindcss/typography')]
}
Loading…
Cancel
Save