mirror of https://github.com/MaxLeiter/Drift
Merge pull request #65 from MaxLeiter/dupePosts
client/server: add the ability to copy a post, view a posts parentpull/59/head
commit
763cb1dadc
@ -0,0 +1,30 @@
|
||||
.title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.badges {
|
||||
display: flex;
|
||||
gap: var(--gap-half);
|
||||
}
|
||||
|
||||
.buttons {
|
||||
display: flex;
|
||||
gap: var(--gap-half);
|
||||
}
|
||||
|
||||
@media screen and (max-width: 700px) {
|
||||
.badges {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.badges > * {
|
||||
width: min-content;
|
||||
}
|
||||
|
||||
.title {
|
||||
flex-direction: column;
|
||||
gap: var(--gap);
|
||||
}
|
||||
}
|
||||
@ -1,51 +1,51 @@
|
||||
.header {
|
||||
.header .title {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: var(--gap);
|
||||
}
|
||||
|
||||
.header .title {
|
||||
.header .title .badges {
|
||||
display: flex;
|
||||
text-align: center;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: var(--gap-half);
|
||||
}
|
||||
|
||||
.header .title h3 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.header .title .badges > * {
|
||||
margin-left: var(--gap);
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.header .buttons {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 900px) {
|
||||
.header {
|
||||
flex-direction: column;
|
||||
gap: var(--gap);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 700px) {
|
||||
.header .title {
|
||||
flex-direction: column;
|
||||
padding-bottom: var(--gap-double);
|
||||
gap: var(--gap-half);
|
||||
}
|
||||
|
||||
.header .title .badges {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.header .title .badges > * {
|
||||
margin-left: 0;
|
||||
width: min-content;
|
||||
}
|
||||
|
||||
.header .title .badges {
|
||||
.header .buttons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,81 @@
|
||||
import styles from '@styles/Home.module.css'
|
||||
import NewPost from '@components/new-post'
|
||||
import Header from '@components/header'
|
||||
import PageSeo from '@components/page-seo'
|
||||
import { Page } from '@geist-ui/core'
|
||||
import Head from 'next/head'
|
||||
import { GetServerSideProps } from 'next'
|
||||
import { Post } from '@lib/types'
|
||||
import cookie from 'cookie'
|
||||
|
||||
const NewFromExisting = ({
|
||||
post,
|
||||
parentId
|
||||
}: {
|
||||
post: Post,
|
||||
parentId: string
|
||||
}) => {
|
||||
console.log(parentId, post)
|
||||
return (
|
||||
<Page className={styles.wrapper}>
|
||||
<PageSeo title="Create a new Drift" />
|
||||
<Head>
|
||||
{/* TODO: solve this. */}
|
||||
{/* eslint-disable-next-line @next/next/no-css-tags */}
|
||||
<link rel="stylesheet" href="/css/react-datepicker.css" />
|
||||
</Head>
|
||||
<Page.Header>
|
||||
<Header />
|
||||
</Page.Header>
|
||||
|
||||
<Page.Content className={styles.main}>
|
||||
<NewPost initialPost={post} newPostParent={parentId} />
|
||||
</Page.Content>
|
||||
</Page >
|
||||
)
|
||||
}
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async ({ req, params }) => {
|
||||
const id = params?.id
|
||||
const redirect = {
|
||||
redirect: {
|
||||
destination: '/new',
|
||||
permanent: false,
|
||||
}
|
||||
}
|
||||
|
||||
if (!id) {
|
||||
return redirect
|
||||
}
|
||||
|
||||
const driftToken = cookie.parse(req.headers.cookie || '')[`drift-token`]
|
||||
|
||||
const post = await fetch(`${process.env.API_URL}/posts/${id}`,
|
||||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `Bearer ${driftToken}`,
|
||||
"x-secret-key": process.env.SECRET_KEY || ""
|
||||
}
|
||||
})
|
||||
|
||||
if (!post.ok) {
|
||||
return redirect
|
||||
}
|
||||
|
||||
const data = await post.json()
|
||||
|
||||
if (!data) {
|
||||
return redirect
|
||||
}
|
||||
|
||||
return {
|
||||
props: {
|
||||
post: data,
|
||||
parentId: id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default NewFromExisting
|
||||
@ -1,37 +1,37 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"plugins": [{ "name": "typescript-plugin-css-modules" }],
|
||||
"target": "es2020",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noImplicitAny": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"strictBindCallApply": true,
|
||||
"strictPropertyInitialization": true,
|
||||
"noImplicitThis": true,
|
||||
"alwaysStrict": true,
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@components/*": ["components/*"],
|
||||
"@lib/*": ["lib/*"],
|
||||
"@styles/*": ["styles/*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
"compilerOptions": {
|
||||
"plugins": [{ "name": "typescript-plugin-css-modules" }],
|
||||
"target": "es2020",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noImplicitAny": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"strictBindCallApply": true,
|
||||
"strictPropertyInitialization": true,
|
||||
"noImplicitThis": true,
|
||||
"alwaysStrict": true,
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@components/*": ["components/*"],
|
||||
"@lib/*": ["lib/*"],
|
||||
"@styles/*": ["styles/*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
||||
@ -1 +1,2 @@
|
||||
require("dotenv").config()
|
||||
require("./src/database").umzug.runAsCLI()
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
"use strict"
|
||||
import { DataTypes } from "sequelize"
|
||||
import type { Migration } from "../database"
|
||||
|
||||
export const up: Migration = async ({ context: queryInterface }) =>
|
||||
queryInterface.addColumn("posts", "parentId", {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: true
|
||||
})
|
||||
|
||||
export const down: Migration = async ({ context: queryInterface }) =>
|
||||
await queryInterface.removeColumn("posts", "parentId")
|
||||
Loading…
Reference in New Issue