mirror of
https://github.com/hilmanski/contentswift.git
synced 2026-08-24 10:05:45 -05:00
adding raw text editor for making content
This commit is contained in:
@@ -11,6 +11,17 @@ def get_post(post_id: int):
|
||||
post = session.get(Post, post_id)
|
||||
return post
|
||||
|
||||
def update_post(post_id: int, data: dict):
|
||||
session = Session(engine)
|
||||
post = session.get(Post, post_id)
|
||||
for key, value in data.items():
|
||||
setattr(post, key, value)
|
||||
session.add(post)
|
||||
session.commit()
|
||||
session.refresh(post)
|
||||
|
||||
return post
|
||||
|
||||
def remove_post(post_id: int):
|
||||
session = Session(engine)
|
||||
post = session.get(Post, post_id)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import os
|
||||
import random
|
||||
# import random
|
||||
from fastapi import FastAPI
|
||||
from dotenv import load_dotenv
|
||||
from serpapi import GoogleSearch
|
||||
@@ -16,7 +16,7 @@ from nltk.util import bigrams, trigrams
|
||||
import operator
|
||||
import nltk
|
||||
|
||||
from .db.post import add_post, save_links, get_post, get_all_post, remove_post
|
||||
from .db.post import add_post, save_links, get_post, get_all_post, remove_post, update_post
|
||||
|
||||
|
||||
|
||||
@@ -98,6 +98,11 @@ def getPost(post_id: str):
|
||||
post = get_post(post_id)
|
||||
return post
|
||||
|
||||
@app.put('/posts/{post_id}')
|
||||
def updatePost(post_id: str, data: dict):
|
||||
post = update_post(post_id, data)
|
||||
return post
|
||||
|
||||
@app.delete('/posts/{post_id}')
|
||||
def deletePost(post_id: str):
|
||||
post = remove_post(post_id)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import Link from "next/link";
|
||||
import Terms from "@/components/Terms";
|
||||
import TextEditor from "@/components/TextEditor";
|
||||
|
||||
async function getData(id: string) {
|
||||
const res = await fetch(`http://localhost:8000/posts/${id}`)
|
||||
@@ -23,10 +24,20 @@ export default async function Editor({
|
||||
const data = await getData(params.id);
|
||||
const searchResult = data.search_result
|
||||
|
||||
|
||||
return (
|
||||
<div className="my-10 max-w-7xl mx-auto">
|
||||
|
||||
<div className="flex justify-between mb-5">
|
||||
<p className="text-xl">
|
||||
Title: {data.title}
|
||||
</p>
|
||||
|
||||
<Link href="/" className="underline">
|
||||
Home
|
||||
</Link>
|
||||
|
||||
</div>
|
||||
|
||||
<section className="fixed">
|
||||
<p>Menu</p>
|
||||
|
||||
@@ -39,98 +50,95 @@ export default async function Editor({
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="ml-[200px] w-8/12">
|
||||
<section className="flex justify-between">
|
||||
|
||||
<div className="flex justify-between">
|
||||
<p className="text-xl">
|
||||
Title: {data.title}
|
||||
</p>
|
||||
|
||||
<Link href="/" className="underline">
|
||||
Home
|
||||
</Link>
|
||||
</div>
|
||||
<section className="ml-[200px] w-3/12 max-h-screen overflow-y-scroll">
|
||||
|
||||
|
||||
{
|
||||
searchResult.answer_box && (
|
||||
<section
|
||||
id="answer-box"
|
||||
className="my-5 p-3 border border-emerald-600 text-sm">
|
||||
<h3 className="text-emerald-700 ">Answer Box (Featued Snippet)</h3>
|
||||
<p className="italic">
|
||||
{
|
||||
searchResult.answer_box.snippet
|
||||
}
|
||||
</p>
|
||||
|
||||
{
|
||||
searchResult.answer_box.list && (
|
||||
<div>
|
||||
<p className="text-bold italic">Info: Features snippet is a list</p>
|
||||
{
|
||||
searchResult.answer_box && (
|
||||
<section
|
||||
id="answer-box"
|
||||
className="my-5 p-3 border border-emerald-600 text-sm">
|
||||
<h3 className="text-emerald-700 ">Answer Box (Featued Snippet)</h3>
|
||||
<p className="italic">
|
||||
{
|
||||
searchResult.answer_box.list.map((item, index) => {
|
||||
return (
|
||||
<div key={index}>
|
||||
<p>{item}</p>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
searchResult.answer_box.snippet
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a className="text-sky-700"
|
||||
href={searchResult.answer_box.link}>
|
||||
source
|
||||
</a>
|
||||
</p>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
searchResult.related_questions.length > 0 && (
|
||||
<section
|
||||
id="related-questions"
|
||||
className="my-5 p-3 border border-emerald-600 text-sm">
|
||||
<h3 className="text-emerald-700 mb-2">Related Questions</h3>
|
||||
{
|
||||
searchResult.related_questions.map((item, index) => {
|
||||
return (
|
||||
<div key={index} className="mb-1">
|
||||
<p className="font-bold"> {item.question} </p>
|
||||
<p className="italic"> {item.snippet} </p>
|
||||
</div>
|
||||
{
|
||||
searchResult.answer_box.list && (
|
||||
<div>
|
||||
<p className="text-bold italic">Info: Features snippet is a list</p>
|
||||
{
|
||||
searchResult.answer_box.list.map((item, index) => {
|
||||
return (
|
||||
<div key={index}>
|
||||
<p>{item}</p>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
searchResult.related_searches.length > 0 && (
|
||||
<section
|
||||
id="related-searches"
|
||||
className="my-5 p-3 border border-emerald-600 text-sm">
|
||||
<h3 className="text-emerald-700 mb-2">Related Searches</h3>
|
||||
{
|
||||
searchResult.related_searches.map((item, index) => {
|
||||
return (
|
||||
<div key={index} className="mb-1">
|
||||
<p className=""> {item.query} </p>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
<p>
|
||||
<a className="text-sky-700"
|
||||
href={searchResult.answer_box.link}>
|
||||
source
|
||||
</a>
|
||||
</p>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
<Terms id={params.id} />
|
||||
{
|
||||
searchResult.related_questions.length > 0 && (
|
||||
<section
|
||||
id="related-questions"
|
||||
className="my-5 p-3 border border-emerald-600 text-sm">
|
||||
<h3 className="text-emerald-700 mb-2">Related Questions</h3>
|
||||
{
|
||||
searchResult.related_questions.map((item, index) => {
|
||||
return (
|
||||
<div key={index} className="mb-1">
|
||||
<p className="font-bold"> {item.question} </p>
|
||||
<p className="italic"> {item.snippet} </p>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
searchResult.related_searches.length > 0 && (
|
||||
<section
|
||||
id="related-searches"
|
||||
className="my-5 p-3 border border-emerald-600 text-sm">
|
||||
<h3 className="text-emerald-700 mb-2">Related Searches</h3>
|
||||
{
|
||||
searchResult.related_searches.map((item, index) => {
|
||||
return (
|
||||
<div key={index} className="mb-1">
|
||||
<p className=""> {item.query} </p>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
<Terms id={params.id} />
|
||||
</section>
|
||||
|
||||
<TextEditor
|
||||
id={params.id}
|
||||
prevContent={data.content} />
|
||||
</section>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
|
||||
export default function TextEditor({id, prevContent}: {id: string, prevContent: string}) {
|
||||
|
||||
const [content, setContent] = useState<string>(prevContent)
|
||||
|
||||
const saveContent = () => {
|
||||
fetch(`http://localhost:8000/posts/${id}/`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
content: content
|
||||
})
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(data => console.log(data))
|
||||
.catch(err => console.log(err))
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="ml-5 w-8/12">
|
||||
<div className="flex justify-between items-center mb-5">
|
||||
<p className="font-bold text-xl">Text Editor</p>
|
||||
<button
|
||||
onClick={() => {saveContent()}}
|
||||
className="bg-sky-400 hover:bg-sky-600 p-3 rounded-lg text-white">
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<textarea
|
||||
value={content || ''}
|
||||
onChange={(e) => {setContent(e.target.value)}}
|
||||
className="w-full h-screen border border-gray-300 p-5"></textarea>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user