diff --git a/.env.local.example b/.env.local.example deleted file mode 100644 index 1c0ba25..0000000 --- a/.env.local.example +++ /dev/null @@ -1,8 +0,0 @@ -DOTNET_SERVER_URL=http://localhost:5000 -NEXT_PUBLIC_SITE_URL=http://localhost:3000 -AUTH0_BASE_URL=http://localhost:3000 -AUTH0_SECRET=9156f409cf1303dea93a850db47a57ed451cc530d4fc1624d0042020eae1e04c - -AUTH0_ISSUER_BASE_URL=https://REPLACE_WITH_AUTH0_DOMAIN -AUTH0_CLIENT_ID=REPLACE_WITH_AUTH0_CLIENT_ID -AUTH0_CLIENT_SECRET=REPLACE_WITH_AUTH0_SECRET diff --git a/.vs/MyFirstBlogFrontEnd/CopilotIndices/17.14.878.3237/CodeChunks.db b/.vs/MyFirstBlogFrontEnd/CopilotIndices/17.14.878.3237/CodeChunks.db new file mode 100644 index 0000000..902f4fb Binary files /dev/null and b/.vs/MyFirstBlogFrontEnd/CopilotIndices/17.14.878.3237/CodeChunks.db differ diff --git a/.vs/MyFirstBlogFrontEnd/CopilotIndices/17.14.878.3237/SemanticSymbols.db b/.vs/MyFirstBlogFrontEnd/CopilotIndices/17.14.878.3237/SemanticSymbols.db new file mode 100644 index 0000000..8ba0de1 Binary files /dev/null and b/.vs/MyFirstBlogFrontEnd/CopilotIndices/17.14.878.3237/SemanticSymbols.db differ diff --git a/.vs/MyFirstBlogFrontEnd/FileContentIndex/f1f97f09-1b39-45ed-93ce-36566599a682.vsidx b/.vs/MyFirstBlogFrontEnd/FileContentIndex/f1f97f09-1b39-45ed-93ce-36566599a682.vsidx new file mode 100644 index 0000000..5fe79f4 Binary files /dev/null and b/.vs/MyFirstBlogFrontEnd/FileContentIndex/f1f97f09-1b39-45ed-93ce-36566599a682.vsidx differ diff --git a/.vs/MyFirstBlogFrontEnd/v17/.wsuo b/.vs/MyFirstBlogFrontEnd/v17/.wsuo new file mode 100644 index 0000000..1c1661a Binary files /dev/null and b/.vs/MyFirstBlogFrontEnd/v17/.wsuo differ diff --git a/.vs/MyFirstBlogFrontEnd/v17/DocumentLayout.backup.json b/.vs/MyFirstBlogFrontEnd/v17/DocumentLayout.backup.json new file mode 100644 index 0000000..37f3aaa --- /dev/null +++ b/.vs/MyFirstBlogFrontEnd/v17/DocumentLayout.backup.json @@ -0,0 +1,12 @@ +{ + "Version": 1, + "WorkspaceRootPath": "M:\\MyFirstBlogFrontEnd\\", + "Documents": [], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [] + } + ] +} \ No newline at end of file diff --git a/.vs/MyFirstBlogFrontEnd/v17/DocumentLayout.json b/.vs/MyFirstBlogFrontEnd/v17/DocumentLayout.json new file mode 100644 index 0000000..37f3aaa --- /dev/null +++ b/.vs/MyFirstBlogFrontEnd/v17/DocumentLayout.json @@ -0,0 +1,12 @@ +{ + "Version": 1, + "WorkspaceRootPath": "M:\\MyFirstBlogFrontEnd\\", + "Documents": [], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [] + } + ] +} \ No newline at end of file diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json new file mode 100644 index 0000000..c3a6e11 --- /dev/null +++ b/.vs/VSWorkspaceState.json @@ -0,0 +1,4 @@ +{ + "ExpandedNodes": [], + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite new file mode 100644 index 0000000..90bebcf Binary files /dev/null and b/.vs/slnx.sqlite differ diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..2ba986f --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "chrome", + "request": "launch", + "name": "Launch Chrome against localhost", + "url": "http://localhost:8080", + "webRoot": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/src/api/axiosConfig.js b/src/api/axiosConfig.js index bd45cb2..6e118ae 100644 --- a/src/api/axiosConfig.js +++ b/src/api/axiosConfig.js @@ -1,12 +1,17 @@ + import axios from "axios" import { isHyperlink } from '@/lib/isHyperlink' const BASE_URL = process.env.DOTNET_SERVER_URL + const AXIOS_BASE = axios.create({ baseURL: BASE_URL, - }) + }) + + const JSON_CLIENT = isHyperlink(BASE_URL) ? AXIOS_BASE : false export default JSON_CLIENT + diff --git a/src/api/postsApi.js b/src/api/postsApi.js index 54f8964..7920f99 100644 --- a/src/api/postsApi.js +++ b/src/api/postsApi.js @@ -1,4 +1,4 @@ -import API from './axiosConfig' +/*import API from './axiosConfig' export const getPosts = () => { try { @@ -12,6 +12,7 @@ export const getPosts = () => { } export const getPost = (postSlug) => { + console.log("Calling:", `${process.env.NEXT_PUBLIC_API_URL}/posts/${postSlug}`); try { return API.get(`/posts/${postSlug}`) .then((res) => res.data) @@ -21,3 +22,27 @@ export const getPost = (postSlug) => { return {} } } +*/ + +import API from './axiosConfig' + +export const getPosts = async () => { + try { + const res = await API.get('/posts/') + return res.data + } catch (e) { + console.error('Error fetching posts:', e) + return [] + } +} + +export const getPost = async (postSlug) => { + console.log("Calling:", `${process.env.NEXT_PUBLIC_API_URL}/posts/${postSlug}`); + try { + const res = await API.get(`/posts/${postSlug}`) + return res.data + } catch (e) { + console.error('Error fetching post:', e) + return {} + } +} diff --git a/src/pages/posts/[slug].jsx b/src/pages/posts/[slug].jsx index b71f258..68cbfd6 100644 --- a/src/pages/posts/[slug].jsx +++ b/src/pages/posts/[slug].jsx @@ -3,36 +3,41 @@ import { getPost, getPosts } from "@/api/postsApi" import { postParameters } from "@/lib/postUtilities" export async function getStaticPaths() { - const posts = await getPosts() - - const postParams = posts ? postParameters(posts) : [] + const posts = await getPosts(); + const postParams = posts ? postParameters(posts) : []; return { paths: postParams, - fallback: false, - } + fallback: 'blocking', + }; } export async function getStaticProps(context) { - const currentPost = await getPost(context.params.slug) + const currentPost = await getPost(context.params.slug); - return { - props: { post: currentPost || {} }, + if (!currentPost || !currentPost.slug) { + return { notFound: true }; } + + return { + props: { post: currentPost }, + }; } export default function Post({ post }) { - const meta = { - author: 'Spencer Sharp', + author: post.author || 'Admin', date: post.createdDate, title: post.title, description: post.body, - } + }; return ( - {post.body} +
+

{post.title}

+

{post.body}

+
- ) + ); } diff --git a/src/pages/posts/new.jsx b/src/pages/posts/new.jsx new file mode 100644 index 0000000..2e4fd0a --- /dev/null +++ b/src/pages/posts/new.jsx @@ -0,0 +1,92 @@ +import { useState } from 'react'; +import { useRouter } from 'next/router'; + +export default function NewPost() { + const [title, setTitle] = useState(''); + const [description, setDescription] = useState(''); + const [errors, setErrors] = useState([]); + const router = useRouter(); + + const handleSubmit = async (e) => { + e.preventDefault(); + const newErrors = []; + + // Client-side validation + if (!title.trim()) { + newErrors.push('Title cannot be blank'); + } + + if (!description.trim()) { + newErrors.push('You cannot send a message with empty description'); + } + + if (newErrors.length > 0) { + setErrors(newErrors); + return; + } + + try { + const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/posts`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ title, description }), + }); + + const data = await res.json(); + + if (res.status === 201) { + const slug = data?.post?.slug || title.toLowerCase().replace(/\s+/g, '-'); + router.push(`/posts/${slug}`); + } else { + setErrors(data.errors || ['Something went wrong']); + } + } catch (err) { + console.error(err); + setErrors(['Server error. Please try again later.']); + } + }; + + return ( +
+

Create New Post

+ + {errors.length > 0 && ( +
+ {errors.map((err, i) => ( +

{err}

+ ))} +
+ )} + +
+
+ + setTitle(e.target.value)} + /> +
+ +
+ +