File styling adjustments
This commit is contained in:
parent
5e976bfc0d
commit
23a850253b
21 changed files with 156 additions and 131 deletions
|
@ -1,3 +1,12 @@
|
|||
.markdownPreview {
|
||||
padding: var(--gap-quarter);
|
||||
}
|
||||
|
||||
.markdownPreview p {
|
||||
margin-top: var(--gap);
|
||||
margin-bottom: var(--gap);
|
||||
}
|
||||
|
||||
.markdownPreview pre {
|
||||
border-radius: 3px;
|
||||
font-family: "Courier New", Courier, monospace;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
background: #efefef;
|
||||
}
|
||||
|
||||
.descriptionContainer {
|
||||
.documentContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 400px;
|
||||
|
|
|
@ -82,7 +82,7 @@ const Document = ({
|
|||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className={styles.descriptionContainer}>
|
||||
<div className={styles.documentContainer}>
|
||||
<DocumentTabs
|
||||
isEditing={true}
|
||||
defaultTab={defaultTab}
|
||||
|
|
|
@ -139,7 +139,7 @@ const Post = ({
|
|||
for (const doc of docs) {
|
||||
if (!doc.title) {
|
||||
setToast({
|
||||
message: "Please fill out all the document titles",
|
||||
message: "Please fill out all the filenames",
|
||||
type: "error"
|
||||
})
|
||||
hasErrored = true
|
||||
|
|
|
@ -77,7 +77,11 @@ const PostFiles = ({
|
|||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<main style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "var(--gap-double)"
|
||||
}}>
|
||||
{post.files?.map(({ id, content, title, html }) => (
|
||||
<DocumentComponent
|
||||
skeleton={false}
|
||||
|
@ -89,7 +93,7 @@ const PostFiles = ({
|
|||
preview={html}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,47 +1,24 @@
|
|||
.card {
|
||||
padding: var(--gap);
|
||||
border: 1px solid var(--light-gray);
|
||||
border-radius: var(--radius);
|
||||
.card header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
padding: 0 16px;
|
||||
background: var(--lighter-gray);
|
||||
border-radius: 8px 8px 0px 0px;
|
||||
}
|
||||
|
||||
.descriptionContainer {
|
||||
.documentContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 400px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.fileNameContainer {
|
||||
font-family: var(--font-mono) !important;
|
||||
border-radius: var(--radius) !important;
|
||||
margin-bottom: var(--gap-half) !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.fileNameContainer span {
|
||||
transition: background-color var(--transition) !important;
|
||||
border-color: var(--light-gray) !important;
|
||||
}
|
||||
|
||||
.fileNameContainer span:target,
|
||||
.fileNameContainer span:hover {
|
||||
background-color: var(--lighter-gray) !important;
|
||||
}
|
||||
|
||||
.fileNameContainer > div {
|
||||
/* Override geist-ui styling */
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.actionWrapper {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.actionWrapper .actions {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
padding: var(--gap);
|
||||
border: 1px solid var(--lighter-gray);
|
||||
border-top: none;
|
||||
border-radius: 0px 0px 8px 8px;
|
||||
}
|
||||
|
||||
.textarea {
|
||||
|
|
|
@ -9,7 +9,6 @@ import Tooltip from "@components/tooltip"
|
|||
import Button from "@components/button"
|
||||
import ButtonGroup from "@components/button-group"
|
||||
import DocumentTabs from "app/(posts)/components/tabs"
|
||||
import Input from "@components/input"
|
||||
import { Download, ExternalLink } from "react-feather"
|
||||
|
||||
type SharedProps = {
|
||||
|
@ -32,32 +31,30 @@ type Props = (
|
|||
|
||||
const DownloadButtons = ({ rawLink }: { rawLink?: string }) => {
|
||||
return (
|
||||
<div className={styles.actionWrapper}>
|
||||
<ButtonGroup className={styles.actions}>
|
||||
<Tooltip content="Download">
|
||||
<Link
|
||||
href={`${rawLink}?download=true`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Button
|
||||
iconRight={<Download />}
|
||||
aria-label="Download"
|
||||
style={{ borderTopRightRadius: 0, borderBottomRightRadius: 0 }}
|
||||
/>
|
||||
</Link>
|
||||
</Tooltip>
|
||||
<Tooltip content="Open raw in new tab">
|
||||
<Link href={rawLink || ""} target="_blank" rel="noopener noreferrer">
|
||||
<Button
|
||||
iconLeft={<ExternalLink />}
|
||||
aria-label="Open raw file in new tab"
|
||||
style={{ borderTopLeftRadius: 0, borderBottomLeftRadius: 0 }}
|
||||
/>
|
||||
</Link>
|
||||
</Tooltip>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
<ButtonGroup>
|
||||
<Tooltip content="Download">
|
||||
<Link
|
||||
href={`${rawLink}?download=true`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Button
|
||||
iconRight={<Download color="var(--fg)" />}
|
||||
aria-label="Download"
|
||||
style={{ border: "none", background: "transparent" }}
|
||||
/>
|
||||
</Link>
|
||||
</Tooltip>
|
||||
<Tooltip content="Open raw in new tab">
|
||||
<Link href={rawLink || ""} target="_blank" rel="noopener noreferrer">
|
||||
<Button
|
||||
iconLeft={<ExternalLink color="var(--fg)" />}
|
||||
aria-label="Open raw file in new tab"
|
||||
style={{ border: "none", background: "transparent" }}
|
||||
/>
|
||||
</Link>
|
||||
</Tooltip>
|
||||
</ButtonGroup>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -67,9 +64,9 @@ const Document = ({ skeleton, ...props }: Props) => {
|
|||
<>
|
||||
<div className={styles.card}>
|
||||
<div className={styles.fileNameContainer}>
|
||||
<Skeleton width={'100%'} height={36} />
|
||||
<Skeleton width={"100%"} height={36} />
|
||||
</div>
|
||||
<div className={styles.descriptionContainer}>
|
||||
<div className={styles.documentContainer}>
|
||||
<Skeleton width={145} height={36} borderRadius={"4px 4px 0 0"} />
|
||||
<Skeleton
|
||||
width={"100%"}
|
||||
|
@ -87,21 +84,21 @@ const Document = ({ skeleton, ...props }: Props) => {
|
|||
return (
|
||||
<>
|
||||
<div className={styles.card}>
|
||||
<Link href={`#${title}`} className={styles.fileNameContainer}>
|
||||
<Input
|
||||
id={`${title}`}
|
||||
width={"100%"}
|
||||
height={"2rem"}
|
||||
style={{ borderRadius: 0 }}
|
||||
value={title || "Untitled"}
|
||||
onChange={() => {}}
|
||||
disabled
|
||||
aria-label="Document title"
|
||||
/>
|
||||
</Link>
|
||||
<div className={styles.descriptionContainer}>
|
||||
{/* Not /api/ because of rewrites defined in next.config.mjs */}
|
||||
<header>
|
||||
<Link
|
||||
href={`#${title}`}
|
||||
aria-label="File"
|
||||
style={{
|
||||
textDecoration: "none",
|
||||
color: "var(--fg)"
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</Link>
|
||||
<DownloadButtons rawLink={`/file/raw/${id}`} />
|
||||
</header>
|
||||
<div className={styles.documentContainer}>
|
||||
{/* Not /api/ because of rewrites defined in next.config.mjs */}
|
||||
<DocumentTabs
|
||||
defaultTab={initialTab}
|
||||
preview={preview}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
.header {
|
||||
flex-direction: column;
|
||||
gap: var(--gap);
|
||||
margin-bottom: var(--gap);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
|
||||
.card .content {
|
||||
padding: var(--gap);
|
||||
padding: var(--gap-half);
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@ type Tab = {
|
|||
|
||||
const Header = () => {
|
||||
const session = useSession()
|
||||
console.log("session", session)
|
||||
const isSignedIn = session?.status === "authenticated"
|
||||
const isAdmin = session?.data?.user?.role === "admin"
|
||||
const isLoading = session?.status === "loading"
|
||||
|
|
|
@ -38,9 +38,12 @@ type InputProps = Omit<Props, "onChange" | "value" | "label" | "aria-label"> &
|
|||
"aria-label": Props["aria-label"]
|
||||
}
|
||||
)
|
||||
// eslint-disable-next-line react/display-name
|
||||
const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
||||
({ label, className, required, width, height, labelClassName, ...props }, ref) => {
|
||||
(
|
||||
{ label, className, required, width, height, labelClassName, ...props },
|
||||
ref
|
||||
) => {
|
||||
const labelId = label?.replace(/\s/g, "-").toLowerCase()
|
||||
return (
|
||||
<div
|
||||
className={styles.wrapper}
|
||||
|
@ -51,7 +54,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|||
>
|
||||
{label && (
|
||||
<label
|
||||
aria-labelledby={label}
|
||||
htmlFor={labelId}
|
||||
className={clsx(styles.label, labelClassName)}
|
||||
>
|
||||
{label}
|
||||
|
@ -59,7 +62,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|||
)}
|
||||
<input
|
||||
ref={ref}
|
||||
id={label}
|
||||
id={labelId}
|
||||
className={clsx(styles.input, label && styles.withLabel, className)}
|
||||
{...props}
|
||||
style={{
|
||||
|
@ -73,4 +76,6 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|||
}
|
||||
)
|
||||
|
||||
Input.displayName = "Input"
|
||||
|
||||
export default Input
|
||||
|
|
|
@ -5,6 +5,5 @@
|
|||
position: relative;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
padding: 0 calc(1.34 * 16px) 0 calc(1.34 * 16px);
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
"use client";
|
||||
import Toast, { Toaster } from "react-hot-toast"
|
||||
|
||||
export type ToastType = "success" | "error" | "loading" | "default"
|
||||
|
|
|
@ -3,19 +3,19 @@
|
|||
}
|
||||
|
||||
[data-side='top'] .tooltip{
|
||||
margin-bottom: var(--gap);
|
||||
margin-bottom: var(--gap-quarter);
|
||||
}
|
||||
|
||||
.tooltip[data-side='bottom'] {
|
||||
margin-top: var(--gap);
|
||||
margin-top: var(--gap-quarter);
|
||||
}
|
||||
|
||||
.tooltip[data-side='left'] {
|
||||
margin-right: var(--gap);
|
||||
margin-right: var(--gap-quarter);
|
||||
}
|
||||
|
||||
.tooltip[data-side='right'] {
|
||||
margin-left: var(--gap);
|
||||
margin-left: var(--gap-quarter);
|
||||
}
|
||||
|
||||
@keyframes fadein {
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import "@styles/globals.css"
|
||||
import { LayoutWrapper } from "./root-layout-wrapper"
|
||||
import { ServerThemeProvider } from "@wits/next-themes"
|
||||
import { Providers } from "./providers"
|
||||
// import { ServerThemeProvider } from "@wits/next-themes"
|
||||
import Page from "@components/page"
|
||||
import { Toasts } from "@components/toasts"
|
||||
import Header from "@components/header"
|
||||
|
||||
interface RootLayoutProps {
|
||||
children: React.ReactNode
|
||||
|
@ -15,11 +18,17 @@ export default async function RootLayout({ children }: RootLayoutProps) {
|
|||
// attribute="data-theme"
|
||||
// enableColorScheme={true}
|
||||
// >
|
||||
<html lang="en">
|
||||
<head />
|
||||
<body>
|
||||
<LayoutWrapper>{children}</LayoutWrapper>
|
||||
</body>
|
||||
</html>
|
||||
<html lang="en">
|
||||
<head />
|
||||
<body>
|
||||
<Toasts />
|
||||
<Page>
|
||||
<Providers>
|
||||
<Header />
|
||||
{children}
|
||||
</Providers>
|
||||
</Page>
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
|
|
14
src/app/providers.tsx
Normal file
14
src/app/providers.tsx
Normal file
|
@ -0,0 +1,14 @@
|
|||
"use client"
|
||||
|
||||
import * as RadixTooltip from "@radix-ui/react-tooltip"
|
||||
import { SessionProvider } from "next-auth/react"
|
||||
|
||||
export function Providers({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<SessionProvider>
|
||||
<RadixTooltip.Provider delayDuration={200}>
|
||||
{children}
|
||||
</RadixTooltip.Provider>
|
||||
</SessionProvider>
|
||||
)
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
"use client"
|
||||
|
||||
import Header from "@components/header"
|
||||
import Page from "@components/page"
|
||||
import { Toasts } from "@components/toasts"
|
||||
import * as RadixTooltip from "@radix-ui/react-tooltip"
|
||||
import { SessionProvider } from "next-auth/react"
|
||||
|
||||
export function LayoutWrapper({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<SessionProvider>
|
||||
<RadixTooltip.Provider delayDuration={200}>
|
||||
<Toasts />
|
||||
<Page>
|
||||
<Header />
|
||||
{children}
|
||||
</Page>
|
||||
</RadixTooltip.Provider>
|
||||
</SessionProvider>
|
||||
)
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
article {
|
||||
max-width: var(--main-content);
|
||||
margin: 0 auto;
|
||||
line-height: 1.9;
|
||||
font-size: 1rem;
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
article video,
|
||||
|
@ -108,6 +109,7 @@ article pre {
|
|||
line-height: 1.8;
|
||||
padding: 1rem;
|
||||
font-size: 0.875rem;
|
||||
background-color: var(--lighter-gray);
|
||||
}
|
||||
|
||||
table {
|
||||
|
|
|
@ -111,11 +111,25 @@ export async function getPostsByUser(userId: User["id"], withFiles?: boolean) {
|
|||
where: {
|
||||
authorId: userId
|
||||
},
|
||||
include: {
|
||||
files: withFiles
|
||||
},
|
||||
orderBy: {
|
||||
createdAt: "desc"
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
title: true,
|
||||
createdAt: true,
|
||||
updatedAt: true,
|
||||
authorId: true,
|
||||
visibility: true,
|
||||
...(withFiles && {
|
||||
files: {
|
||||
select: {
|
||||
id: true,
|
||||
title: true,
|
||||
createdAt: true,
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
@ -38,7 +38,8 @@
|
|||
"react-hot-toast": "2.4.0-beta.0",
|
||||
"server-only": "^0.0.1",
|
||||
"textarea-markdown-editor": "1.0.4",
|
||||
"ts-jest": "^29.0.3"
|
||||
"ts-jest": "^29.0.3",
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next/bundle-analyzer": "13.0.7-canary.4",
|
||||
|
@ -48,6 +49,7 @@
|
|||
"@types/react": "18.0.9",
|
||||
"@types/react-datepicker": "4.4.1",
|
||||
"@types/react-dom": "18.0.3",
|
||||
"@types/uuid": "^9.0.0",
|
||||
"clsx": "^1.2.1",
|
||||
"cross-env": "7.0.3",
|
||||
"csstype": "^3.1.1",
|
||||
|
|
|
@ -16,6 +16,7 @@ specifiers:
|
|||
'@types/react': 18.0.9
|
||||
'@types/react-datepicker': 4.4.1
|
||||
'@types/react-dom': 18.0.3
|
||||
'@types/uuid': ^9.0.0
|
||||
'@wcj/markdown-to-html': ^2.1.2
|
||||
'@wits/next-themes': 0.2.14
|
||||
client-only: ^0.0.1
|
||||
|
@ -44,6 +45,7 @@ specifiers:
|
|||
ts-jest: ^29.0.3
|
||||
typescript: 4.6.4
|
||||
typescript-plugin-css-modules: 3.4.0
|
||||
uuid: ^9.0.0
|
||||
|
||||
dependencies:
|
||||
'@next-auth/prisma-adapter': 1.0.5_64qbzg5ec56bux2misz3l4u6g4
|
||||
|
@ -72,6 +74,7 @@ dependencies:
|
|||
server-only: 0.0.1
|
||||
textarea-markdown-editor: 1.0.4_biqbaboplfbrettd7655fr4n2y
|
||||
ts-jest: 29.0.3_7hcmezpa7bajbjecov7p46z4aa
|
||||
uuid: 9.0.0
|
||||
|
||||
optionalDependencies:
|
||||
sharp: 0.31.2
|
||||
|
@ -84,6 +87,7 @@ devDependencies:
|
|||
'@types/react': 18.0.9
|
||||
'@types/react-datepicker': 4.4.1_biqbaboplfbrettd7655fr4n2y
|
||||
'@types/react-dom': 18.0.3
|
||||
'@types/uuid': 9.0.0
|
||||
clsx: 1.2.1
|
||||
cross-env: 7.0.3
|
||||
csstype: 3.1.1
|
||||
|
@ -1581,6 +1585,10 @@ packages:
|
|||
resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==}
|
||||
dev: false
|
||||
|
||||
/@types/uuid/9.0.0:
|
||||
resolution: {integrity: sha512-kr90f+ERiQtKWMz5rP32ltJ/BtULDI5RVO0uavn1HQUOwjx0R1h0rnDYNL0CepF1zL5bSY6FISAfd9tOdDhU5Q==}
|
||||
dev: true
|
||||
|
||||
/@types/yargs-parser/21.0.0:
|
||||
resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==}
|
||||
dev: false
|
||||
|
@ -6950,6 +6958,11 @@ packages:
|
|||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/uuid/9.0.0:
|
||||
resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/uvu/0.5.6:
|
||||
resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==}
|
||||
engines: {node: '>=8'}
|
||||
|
|
Loading…
Reference in a new issue