Skip to content

Commit

Permalink
Merge pull request #29 from HereEast/feat/questions-page
Browse files Browse the repository at this point in the history
feat: Add all Questions page
  • Loading branch information
HereEast authored Feb 16, 2025
2 parents 8c308f7 + a3b7776 commit 53bd0bb
Show file tree
Hide file tree
Showing 14 changed files with 90 additions and 156 deletions.
4 changes: 2 additions & 2 deletions src/api-client/answers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ export async function submitAnswers(formData: IFormDataProps[]) {
}
}

// GET ANSWERS BY SLUG
export async function getAnswersBySlug(slug: string) {
// GET ANSWERS BY PERSON SLUG
export async function getAnswersByPersonSlug(slug: string) {
try {
const answersResponse = await fetch(`${BASE_URL}/api/answers/${slug}`);

Expand Down
17 changes: 11 additions & 6 deletions src/api-client/questions.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import axios from "axios";

import { IQuestion } from "~/models/Question";
import { BASE_URL } from "~/utils/constants";

// GET ALL QUESTIONS
export async function getQuestions() {
try {
const response = await axios.get<IQuestion[]>(`/api/questions`);
const response = await fetch(`${BASE_URL}/api/questions`);

if (!response.ok) {
throw new Error("🔴 Data fetch failed (questions)");
}

const data = response.data;
const people: IQuestion[] = await response.json();

return data;
return people;
} catch (err) {
if (err instanceof Error) {
console.log(err);
console.log("🔴 Error:", err.message);
}

return null;
}
}
2 changes: 1 addition & 1 deletion src/app/api/answers/[slug]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export async function GET(req: Request, { params }: ReqParams) {

const activeAnswers = answers.filter((answer) => {
const question = answer.questionId as IQuestion;
return question.active === true;
return question.isActive === true;
});

const result = activeAnswers.sort((a, b) => {
Expand Down
2 changes: 1 addition & 1 deletion src/app/api/questions/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export async function GET() {
try {
await connectDB();

const questions: IQuestion[] = await Question.find()
const questions: IQuestion[] = await Question.find({ isActive: true })
.sort({ order: 1 })
.exec();

Expand Down
6 changes: 3 additions & 3 deletions src/app/not-found.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import Link from "next/link";

import { PageLayout } from "~/components/layouts/PageLayout";
import { PageContainer } from "~/components/layouts/PageContainer";
import { PAGE } from "~/utils/constants";

export default function NotFound() {
return (
<PageLayout className="grow">
<PageContainer className="grow">
<section className="flex h-full items-center justify-center">
<div className="space-y-6 text-center">
<h2 className="text-2xl">
Expand All @@ -20,6 +20,6 @@ export default function NotFound() {
</Link>
</div>
</section>
</PageLayout>
</PageContainer>
);
}
4 changes: 2 additions & 2 deletions src/app/people/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { QAPage } from "~/components/layouts/QAPage";
import { PersonQAPage } from "~/components/layouts/PersonQAPage";

import { connectDB } from "~/app/lib/connectDB";
import { Person, IPerson } from "~/models/Person";
Expand Down Expand Up @@ -66,5 +66,5 @@ export async function generateStaticParams() {
}

export default async function PersonPage({ params }: PersonPageProps) {
return <QAPage slug={params.slug} />;
return <PersonQAPage slug={params.slug} />;
}
84 changes: 3 additions & 81 deletions src/app/questions/page.tsx
Original file line number Diff line number Diff line change
@@ -1,83 +1,5 @@
"use client";
import { QuestionsPage } from "~/components/layouts/QuestionsPage";

import { FormEvent, useState } from "react";

import { PageLayout } from "~/components/layouts/PageLayout";

import { IFormDataProps, submitAnswers } from "~/api-client/answers";
import { useQuestions } from "~/hooks";

export default function QuestionsPage() {
const { data: questions, isLoading } = useQuestions();

const [error, setError] = useState("");

async function handleSubmit(e: FormEvent<HTMLFormElement>) {
e.preventDefault();
setError("");

const formData = new FormData(e.currentTarget);

const isEmptyValue = Array.from(formData.values()).some(
(value) => String(value).trim().length === 0,
);

if (isEmptyValue) {
setError("All inputs are required.");
return;
}

const answersData: IFormDataProps[] = Array.from(formData.entries()).map(
([questionId, answer], index) => {
return {
questionId,
question: questions?.[index].body || "",
answer: answer as string,
};
},
);

console.log(answersData);

const result = await submitAnswers(answersData);
console.log(result); // Console
}

return (
<PageLayout className="bg-stone-200 px-20">
{isLoading && <div>Loading...</div>}

{error && (
<div className="mb-6 bg-red-600 px-4 py-3 text-base text-stone-50">
{error}
</div>
)}

{questions && questions.length > 0 && (
<form onSubmit={handleSubmit} className="mb-20 space-y-10">
{questions.map((question, index) => (
<div className="flex w-full flex-col gap-2" key={index}>
<label
htmlFor={String(question._id)}
className="font-medium tracking-tight"
>
{`${question.order}. ${question.body}`}
</label>

<textarea
id={String(question._id)}
name={String(question._id)}
rows={6}
className="border border-stone-700 px-5 py-4 text-base outline-none focus:border-stone-400"
/>
</div>
))}

<button type="submit" className="w-40 bg-black p-4 text-stone-50">
Submit
</button>
</form>
)}
</PageLayout>
);
export default function Questions() {
return <QuestionsPage />;
}
6 changes: 3 additions & 3 deletions src/components/layouts/BacklogPage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Link from "next/link";
import { CheckIcon } from "@heroicons/react/16/solid";

import { PageLayout } from "./PageLayout";
import { PageContainer } from "./PageContainer";
import { BacklogCountLabel } from "../BacklogPreview";

import { EMAIL } from "~/utils/constants";
Expand All @@ -13,7 +13,7 @@ export function BacklogPage() {
const doneList = BACKLOG.items.filter((item) => item.done);

return (
<PageLayout className="max-w-4xl">
<PageContainer className="max-w-4xl">
<div className="w-full rounded-xl bg-stone-100 p-8 md:p-10">
{/* Header */}
<div className="mb-6 flex w-full items-center justify-between">
Expand Down Expand Up @@ -57,7 +57,7 @@ export function BacklogPage() {
</div>
</div>
</div>
</PageLayout>
</PageContainer>
);
}

Expand Down
6 changes: 3 additions & 3 deletions src/components/layouts/HomePage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { MainCards } from "../MainCards";
import { ShareForm } from "../ShareForm";
import { SubscribeForm } from "../SubscribeForm";
import { PageLayout } from "./PageLayout";
import { PageContainer } from "./PageContainer";
import { About } from "../About";
import { BacklogPreview } from "../BacklogPreview";

Expand All @@ -11,7 +11,7 @@ export async function HomePage() {
const people = await getPeople();

return (
<PageLayout>
<PageContainer>
{people && (
<>
{/* Add skeletons for cards */}
Expand Down Expand Up @@ -42,6 +42,6 @@ export async function HomePage() {
</div>
</>
)}
</PageLayout>
</PageContainer>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ interface PageLayoutProps {
className?: string;
}

export function PageLayout({ children, className = "" }: PageLayoutProps) {
export function PageContainer({ children, className = "" }: PageLayoutProps) {
return (
<div
className={cn("relative mx-auto max-w-7xl px-2 py-10 sm:px-4", className)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,27 @@ import { notFound } from "next/navigation";

import { ShareForm } from "../ShareForm";
import { PersonPreview } from "../PersonPreview";
import { PageLayout } from "./PageLayout";
import { PageContainer } from "./PageContainer";
import { Content } from "../Content";
import { SidePeoplePanel } from "../SidePeoplePanel";

import { getPerson } from "~/api-client/people";
import { getAnswersBySlug } from "~/api-client/answers";
import { getAnswersByPersonSlug } from "~/api-client/answers";

interface QAPageProps {
slug: string;
}

export async function QAPage({ slug }: QAPageProps) {
export async function PersonQAPage({ slug }: QAPageProps) {
const person = await getPerson(slug);
const answers = await getAnswersBySlug(slug);
const answers = await getAnswersByPersonSlug(slug);

if (!person || !answers) {
notFound();
}

return (
<PageLayout className="min-h-screen max-w-full gap-10 pt-4 sm:pt-10 lg:grid lg:grid-cols-[auto_80px]">
<PageContainer className="min-h-screen max-w-full gap-10 pt-4 sm:pt-10 lg:grid lg:grid-cols-[auto_80px]">
{answers && person && (
<>
<div className="space-y-16">
Expand Down Expand Up @@ -61,6 +61,6 @@ export async function QAPage({ slug }: QAPageProps) {
</aside>
</>
)}
</PageLayout>
</PageContainer>
);
}
50 changes: 50 additions & 0 deletions src/components/layouts/QuestionsPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import Link from "next/link";
import { notFound } from "next/navigation";

import { PageContainer } from "./PageContainer";

import { getQuestions } from "~/api-client/questions";
import { IQuestion } from "~/models/Question";
import { BASE_URL } from "~/utils/constants";

export async function QuestionsPage() {
const questions = await getQuestions();

console.log(questions);

if (!questions) {
notFound();
}

return (
<PageContainer className="max-w-4xl">
{questions && (
<ul className="space-y-1">
{questions.map((item, index) => (
<li key={index}>
<QuestionItem question={item} />
</li>
))}
</ul>
)}
</PageContainer>
);
}

// Question Item
interface QuestionItemProps {
question: IQuestion;
}

function QuestionItem({ question }: QuestionItemProps) {
return (
question && (
<Link
href={`${BASE_URL}/questions/${question.slug}`}
className="inline-block w-full rounded-full bg-stone-100 px-8 py-4 text-xl hover:bg-stone-900 hover:text-stone-50"
>
<span>{question.body}</span>
</Link>
)
);
}
45 changes: 0 additions & 45 deletions src/hooks/index.ts

This file was deleted.

Loading

0 comments on commit 53bd0bb

Please sign in to comment.