Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 7 additions & 9 deletions components/Feeds.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,22 @@ export interface FeedsProps {

export const Feeds = (props: FeedsProps) => {
return (
<div className="mt-10 grid grid-cols-1 md:grid-cols-3 gap-4 justify-items-center">
<div className="columns-2 md:columns-2 lg:columns-3 columns-1 gap-8 px-8 mt-10 container ">
{props.feeds.map((feed) => (
<a
key={feed.link}
href={feed.link}
className="article md:m-0 bg-white p-0 md:p-6 block w-5/6 md:max-w-sm md:max-h-sm rounded-lg border border-black hover:shadow-2xl dark:bg-black dark:border-black dark:hover:bg-black"
>
<h6 className="font-extralight text-xs md:text-sm md:p-0">
<div key={feed.link} className=" break-inside-avoid-column article w-full bg-white p-0 md:p-6 block mb-8 md:mb-4 rounded-lg bg-zinc-100 hover:shadow-xl dark:bg-black dark:border-black dark:hover:bg-black">
<a href={feed.link} target={'blank'}>
<h6 className=" text-fuchsia-800 text-xs md:text-sm md:p-0">
{feed.source}
</h6>
<h5 className="p-2 md:p-2 text-xl md:text-2xl text-start font-bold tracking-tight text-gray-900 dark:text-white">
<h5 className="p-2 md:p-2 text-xl md:text-2xl text-start font-bold tracking-tight mb-5 text-gray-700 dark:text-white">
{feed.title}
</h5>
<hr />
<p className="m-2 md:m-2 text-sm md:text-base feed text-justify text-gray-700 dark:text-gray-400">
<p className="m-2 text-sm py-4 feed leading-relaxed text-gray-700 dark:text-gray-400">
{feed.summary}
</p>
</a>
</div>
))}
</div>
);
Expand Down
13 changes: 0 additions & 13 deletions components/Header.tsx

This file was deleted.

65 changes: 65 additions & 0 deletions components/SearchForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { FormEvent, FunctionComponent, useState } from "react";

interface SearchFormProps {
onSubmitted: (query: string) => void;
}
const SearchForm: FunctionComponent<SearchFormProps> = ({ onSubmitted }) => {
const [query, setQuery] = useState<string>("");

const handleQuerySubmitRequest = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
onSubmitted(query);
};

return (
<form
className="w-80 mx-auto md:p-0 mb-10"
onSubmit={handleQuerySubmitRequest}
>
<label
htmlFor="default-search"
className="text-sm font-medium text-gray-900 sr-only dark:text-gray-300"
>
Search
</label>
<div className="relative">
<div className="flex absolute inset-y-0 left-0 items-center pl-3 pointer-events-none">
<svg
aria-hidden="true"
className="w-5 h-5 text-gray-500 dark:text-gray-400"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
></path>
</svg>
</div>
<div className="flex justify-center items-center text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
<input
type="search"
value={query}
onChange={(e) => setQuery(e.target.value)}
id="default-search"
className="outline outline-0 md:p-4 md:pl-10 text-center md:text-start bg-gray-50 w-full h-14 md:h-auto text-md md:text-sm"
placeholder="Start search..."
required
></input>
<button
type="submit"
className="text-white mr-2 md:h-auto w-2/4 md:w-1/2 bg-black hover:bg-black focus:ring-4 focus:outline-none focus:ring-black font-medium rounded-lg text-sm md:text-sm p-2 md:px-4 md:py-2 dark:bg-black dark:hover:bg-black dark:focus:ring-black "
>
Search
</button>
</div>
</div>
</form>
);
};

export default SearchForm;
File renamed without changes.
27 changes: 27 additions & 0 deletions components/layouts/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Link from "next/link";
import { FunctionComponent } from "react";

interface HeaderProps {
hideTagline?: boolean;
}
export const Header: FunctionComponent<HeaderProps> = ({ hideTagline }) => {
return (
<header className="header text-center flex flex-col p-0 md:p-10">
<h1 className="title p-5 md:p-0 text-5xl md:text-8xl font-black">
Unconditional.
</h1>
{!hideTagline && (
<div className="flex flex-row justify-center items-center p-0 md:p-3 pb-10 md:pb-0">
<h2 className="subtitle text-md md:text-xl">
Give to your think an{" "}
</h2>
<Link href="/about">
<div className="cursor-pointer font-bold text-sm md:text-xl text-transparent bg-clip-text bg-gradient-to-r from-purple-400 to-pink-600 border border-black rounded-lg p-3 block md:inline md:w-auto mx-2">
Unconditional think
</div>
</Link>
</div>
)}
</header>
);
};
62 changes: 62 additions & 0 deletions components/layouts/Layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { FunctionComponent } from "react";
import Head from "next/head";
import Footer from "./Footer";
import { Header } from "./Header";
import SearchForm from "../SearchForm";
import { useRouter } from "next/router";

interface LayoutProps {
children: React.ReactNode;
hideSearchBar?: boolean;
}
const Layout: FunctionComponent<LayoutProps> = ({
children,
hideSearchBar,
}) => {
const router = useRouter();

const onSubmitted = (query: string) => {
router.push({
pathname: `/search/${query}`,
});
};

return (
<>
<Head>
<title>Unconditional.</title>
<meta name="description" content="Unconditional" />
<link
rel="apple-touch-icon"
sizes="180x180"
href="/apple-touch-icon.png"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/favicon-16x16.png"
/>
<link rel="manifest" href="/site.webmanifest" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
</Head>
<div className="flex flex-col h-screen ">
<Header hideTagline={hideSearchBar} />
{!hideSearchBar && <SearchForm onSubmitted={onSubmitted} />}
<hr />
<main className="m-auto md:mb-0 pb-10 md:overflow-y-visible">
{children}
</main>
<Footer />
</div>
</>
);
};

export default Layout;
2 changes: 1 addition & 1 deletion generated/core/ApiError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class ApiError extends Error {
constructor(
request: ApiRequestOptions,
response: ApiResult,
message: string
message: string,
) {
super(message);

Expand Down
8 changes: 4 additions & 4 deletions generated/core/CancelablePromise.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ export class CancelablePromise<T> implements Promise<T> {
executor: (
resolve: (value: T | PromiseLike<T>) => void,
reject: (reason?: any) => void,
onCancel: OnCancel
) => void
onCancel: OnCancel,
) => void,
) {
this._isResolved = false;
this._isRejected = false;
Expand Down Expand Up @@ -87,13 +87,13 @@ export class CancelablePromise<T> implements Promise<T> {

public then<TResult1 = T, TResult2 = never>(
onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,
onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null,
): Promise<TResult1 | TResult2> {
return this._promise.then(onFulfilled, onRejected);
}

public catch<TResult = never>(
onRejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null
onRejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null,
): Promise<T | TResult> {
return this._promise.catch(onRejected);
}
Expand Down
20 changes: 10 additions & 10 deletions generated/core/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { OnCancel } from "./CancelablePromise";
import type { OpenAPIConfig } from "./OpenAPI";

const isDefined = <T>(
value: T | null | undefined
value: T | null | undefined,
): value is Exclude<T, null | undefined> => {
return value !== undefined && value !== null;
};
Expand Down Expand Up @@ -132,7 +132,7 @@ type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;

const resolve = async <T>(
options: ApiRequestOptions,
resolver?: T | Resolver<T>
resolver?: T | Resolver<T>,
): Promise<T | undefined> => {
if (typeof resolver === "function") {
return (resolver as Resolver<T>)(options);
Expand All @@ -142,7 +142,7 @@ const resolve = async <T>(

const getHeaders = async (
config: OpenAPIConfig,
options: ApiRequestOptions
options: ApiRequestOptions,
): Promise<Headers> => {
const token = await resolve(options, config.TOKEN);
const username = await resolve(options, config.USERNAME);
Expand All @@ -160,7 +160,7 @@ const getHeaders = async (
...headers,
[key]: String(value),
}),
{} as Record<string, string>
{} as Record<string, string>,
);

if (isStringWithValue(token)) {
Expand Down Expand Up @@ -211,7 +211,7 @@ export const sendRequest = async (
body: any,
formData: FormData | undefined,
headers: Headers,
onCancel: OnCancel
onCancel: OnCancel,
): Promise<Response> => {
const controller = new AbortController();

Expand All @@ -233,7 +233,7 @@ export const sendRequest = async (

const getResponseHeader = (
response: Response,
responseHeader?: string
responseHeader?: string,
): string | undefined => {
if (responseHeader) {
const content = response.headers.get(responseHeader);
Expand Down Expand Up @@ -265,7 +265,7 @@ const getResponseBody = async (response: Response): Promise<any> => {

const catchErrorCodes = (
options: ApiRequestOptions,
result: ApiResult
result: ApiResult,
): void => {
const errors: Record<number, string> = {
400: "Bad Request",
Expand Down Expand Up @@ -297,7 +297,7 @@ const catchErrorCodes = (
*/
export const request = <T>(
config: OpenAPIConfig,
options: ApiRequestOptions
options: ApiRequestOptions,
): CancelablePromise<T> => {
return new CancelablePromise(async (resolve, reject, onCancel) => {
try {
Expand All @@ -314,12 +314,12 @@ export const request = <T>(
body,
formData,
headers,
onCancel
onCancel,
);
const responseBody = await getResponseBody(response);
const responseHeader = getResponseHeader(
response,
options.responseHeader
options.responseHeader,
);

const result: ApiResult = {
Expand Down
31 changes: 31 additions & 0 deletions generated/hooks/usefeeds.hook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import useSWR, { Fetcher } from "swr";
import { FeedItem } from "../models/FeedItem";
import { DefaultService } from "../services/DefaultService";
import { KeyedMutator } from "swr/_internal";

const fetcher: Fetcher<FeedItem[], string> = (query) =>
DefaultService.getV1SearchFeed(query);

type IUseFeedsOutcome = {
feeds: FeedItem[] | undefined;
error: any;
isLoading: boolean;
mutate: KeyedMutator<FeedItem[]>;
areFeedsEmpty: boolean;
};
type IUseFeeds = {
(query: string | undefined): IUseFeedsOutcome;
};

const useFeeds: IUseFeeds = (query: string | undefined) => {
const { data, error, isLoading, mutate } = useSWR(query, fetcher);
return {
feeds: data,
error,
isLoading,
mutate,
areFeedsEmpty: !isLoading && !!query && (!data || data.length === 0),
};
};

export default useFeeds;
2 changes: 1 addition & 1 deletion generated/services/DefaultService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class DefaultService {
* @throws ApiError
*/
public static getV1SearchFeed(
query: string
query: string,
): CancelablePromise<Array<FeedItem>> {
return __request(OpenAPI, {
method: "GET",
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"react-icons": "^4.6.0",
"react-is": "^18.2.0",
"styled-components": "^5.3.11",
"swr": "^2.2.2",
"tailwindcss": "^3.1.8"
},
"devDependencies": {
Expand Down
10 changes: 7 additions & 3 deletions pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import "../styles/globals.css";
import { Analytics } from "@vercel/analytics/react";
import type { AppProps } from "next/app";
import Layout from "../components/layouts/Layout";

function MyApp({ Component, pageProps }: AppProps) {
interface PageProps {
hideSearchBar?: boolean;
}
function MyApp({ Component, pageProps }: AppProps<PageProps>) {
return (
<>
<Layout hideSearchBar={pageProps.hideSearchBar}>
<Component {...pageProps} />
<Analytics />
</>
</Layout>
);
}

Expand Down
Loading