Enforced actual types in typescript

This commit is contained in:
Imbus 2023-11-13 12:00:46 +01:00
parent 7f9bddb00f
commit d3a10b062d
11 changed files with 54 additions and 44 deletions

View file

@ -4,4 +4,7 @@ module.exports = {
parser: '@typescript-eslint/parser', parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'], plugins: ['@typescript-eslint'],
root: true, root: true,
"rules": {
"@typescript-eslint/explicit-function-return-type": "warn"
}
}; };

View file

@ -1,4 +1,6 @@
export function Arrow() { import { JSXElement } from "solid-js";
export function Arrow(): JSXElement {
return ( return (
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"

View file

@ -1,9 +1,9 @@
import { onCleanup, useContext } from "solid-js"; import { JSXElement, onCleanup, useContext } from "solid-js";
import { ModalContext } from "./Root"; import { ModalContext } from "./Root";
import { LoginForm } from "./RegLogin/Login"; import { LoginForm } from "./RegLogin/Login";
import { RegisterForm } from "./RegLogin/Register"; import { RegisterForm } from "./RegLogin/Register";
export function LoginModal() { export function LoginModal(): JSXElement {
const modal_ctx = useContext(ModalContext); const modal_ctx = useContext(ModalContext);
if (!modal_ctx) { if (!modal_ctx) {
@ -11,7 +11,7 @@ export function LoginModal() {
return null; return null;
} }
const closeModal = () => { const closeModal = (): void => {
modal_ctx.setLoginModalOpen(false); modal_ctx.setLoginModalOpen(false);
}; };

View file

@ -4,7 +4,7 @@ import { LoginContext } from "./Root";
import { ModalContext } from "./Root"; import { ModalContext } from "./Root";
// Represents a single list item in the menu bar // Represents a single list item in the menu bar
function MenuItem(props: { href: string; children: JSXElement }) { function MenuItem(props: { href: string; children: JSXElement }): JSXElement {
return ( return (
<li> <li>
<A class="justify-center" href={props.href} end> <A class="justify-center" href={props.href} end>
@ -15,7 +15,7 @@ function MenuItem(props: { href: string; children: JSXElement }) {
} }
// Represents the menu bar at the top of the page // Represents the menu bar at the top of the page
function Menu() { function Menu(): JSXElement {
const login_ctx = useContext(LoginContext); const login_ctx = useContext(LoginContext);
return ( return (
<ul class="menu md:menu-horizontal rounded-box"> <ul class="menu md:menu-horizontal rounded-box">
@ -25,12 +25,12 @@ function Menu() {
); );
} }
export function Navbar() { export function Navbar(): JSXElement {
const modal_ctx = useContext(ModalContext); const modal_ctx = useContext(ModalContext);
const login_ctx = useContext(LoginContext); const login_ctx = useContext(LoginContext);
const [buttonText, setButtonText] = createSignal("Login"); const [buttonText, setButtonText] = createSignal("Login");
const logout = () => { const logout = (): void => {
localStorage.removeItem("token"); localStorage.removeItem("token");
localStorage.removeItem("username"); localStorage.removeItem("username");
login_ctx?.setToken(""); login_ctx?.setToken("");
@ -38,7 +38,7 @@ export function Navbar() {
}; };
// Function to instantly elect 50 cent as president and declare war on north korea // Function to instantly elect 50 cent as president and declare war on north korea
const capitalizeFirst = (str: string) => { const capitalizeFirst = (str: string): string => {
return str.charAt(0).toUpperCase() + str.slice(1); return str.charAt(0).toUpperCase() + str.slice(1);
}; };
@ -48,7 +48,7 @@ export function Navbar() {
else setButtonText("Login"); else setButtonText("Login");
}, 0); }, 0);
const clickHandler = () => { const clickHandler = (): void => {
if (login_ctx?.token() != "") logout(); if (login_ctx?.token() != "") logout();
else modal_ctx?.setLoginModalOpen(true); else modal_ctx?.setLoginModalOpen(true);
}; };

View file

@ -1,18 +1,17 @@
import { Show, createSignal, useContext } from "solid-js"; import { JSXElement, Show, createSignal, useContext } from "solid-js";
import { createPost } from "./api"; import { createPost } from "./api";
import { NewPost } from "./api"; import { NewPost } from "./api";
import { useNavigate } from "@solidjs/router"; import { useNavigate } from "@solidjs/router";
import { LoginContext } from "./Root"; import { LoginContext } from "./Root";
export function NewPostInputArea(): JSXElement {
export function NewPostInputArea() {
const [content, setContent] = createSignal(""); const [content, setContent] = createSignal("");
const [waiting, setWaiting] = createSignal(false); const [waiting, setWaiting] = createSignal(false);
const login_ctx = useContext(LoginContext); const login_ctx = useContext(LoginContext);
const nav = useNavigate(); const nav = useNavigate();
const sendPost = () => { const sendPost = (): void => {
setWaiting(true); setWaiting(true);
const response = createPost({ const response = createPost({
@ -32,20 +31,24 @@ export function NewPostInputArea() {
return ( return (
<Show <Show
when={!waiting()} when={!waiting()}
fallback={<span class="loading loading-spinner loading-lg self-center"></span>} fallback={
<span class="loading loading-spinner loading-lg self-center"></span>
}
> >
<div class="flex flex-col w-full space-y-2"> <div class="flex flex-col w-full space-y-2">
<textarea <textarea
class="textarea textarea-bordered h-32" class="textarea textarea-bordered h-32"
placeholder="Speak your mind..." placeholder="Speak your mind..."
maxLength={500} maxLength={500}
oninput={(input) => { oninput={(input): void => {
setContent(input.target.value); setContent(input.target.value);
}} }}
></textarea> ></textarea>
<button <button
class={"btn btn-primary self-end btn-sm" + class={
(content() == "" ? " btn-disabled" : "")} "btn btn-primary self-end btn-sm" +
(content() == "" ? " btn-disabled" : "")
}
onclick={sendPost} onclick={sendPost}
> >
Submit Submit

View file

@ -1,10 +1,10 @@
import { createSignal } from "solid-js"; import { JSXElement, createSignal } from "solid-js";
import { getPosts } from "./api"; import { getPosts } from "./api";
import { Post } from "./api"; import { Post } from "./api";
import { useNavigate } from "@solidjs/router"; import { useNavigate } from "@solidjs/router";
import { Arrow } from "./Icons"; import { Arrow } from "./Icons";
export function Posts() { export function Posts(): JSXElement {
const [posts, setPosts] = createSignal([] as Post[]); const [posts, setPosts] = createSignal([] as Post[]);
const [loading, setLoading] = createSignal(true); const [loading, setLoading] = createSignal(true);
@ -27,14 +27,17 @@ export function Posts() {
} }
// This is the card container for a post // This is the card container for a post
export function PostSegment({ post }: { post: Post }) { export function PostSegment({ post }: { post: Post }): JSXElement {
const nav = useNavigate(); const nav = useNavigate();
return ( return (
<div class="card border-b-2 flex-grow border-b-base-300 bg-base-200 hover:bg-base-300 compact text-base-content w-full"> <div class="card border-b-2 flex-grow border-b-base-300 bg-base-200 hover:bg-base-300 compact text-base-content w-full">
<div class="card-body"> <div class="card-body">
<p class="text-base-content break-words">{post?.content}</p> <p class="text-base-content break-words">{post?.content}</p>
<div class="card-actions justify-end"> <div class="card-actions justify-end">
<button onClick={() => nav("/post/" + post?.id)} class="btn btn-xs"> <button
onClick={(): void => nav("/post/" + post?.id)}
class="btn btn-xs"
>
<Arrow /> <Arrow />
</button> </button>
</div> </div>
@ -42,5 +45,3 @@ export function PostSegment({ post }: { post: Post }) {
</div> </div>
); );
} }

View file

@ -2,9 +2,10 @@ import { Route, Routes } from "@solidjs/router";
import { Posts } from "./Posts"; import { Posts } from "./Posts";
import { SinglePost } from "./SinglePost"; import { SinglePost } from "./SinglePost";
import { NewPostInputArea } from "./NewPost"; import { NewPostInputArea } from "./NewPost";
import { JSXElement } from "solid-js";
// Primary is the section of the page that holds the main content // Primary is the section of the page that holds the main content
export function Primary() { export function Primary(): JSXElement {
return ( return (
<Routes> <Routes>
<Route path="/" element={<Posts />} /> <Route path="/" element={<Posts />} />

View file

@ -1,7 +1,7 @@
import { createSignal, useContext } from "solid-js"; import { JSXElement, createSignal, useContext } from "solid-js";
import { LoginContext, ModalContext } from "../Root"; import { LoginContext, ModalContext } from "../Root";
export function LoginForm() { export function LoginForm(): JSXElement {
const modal_ctx = useContext(ModalContext); const modal_ctx = useContext(ModalContext);
const login_ctx = useContext(LoginContext); const login_ctx = useContext(LoginContext);
const [username, setUsername] = createSignal<string>(""); const [username, setUsername] = createSignal<string>("");
@ -9,7 +9,7 @@ export function LoginForm() {
const [waiting, setWaiting] = createSignal(false); const [waiting, setWaiting] = createSignal(false);
const [error, setError] = createSignal(false); const [error, setError] = createSignal(false);
async function loginFailed() { async function loginFailed(): Promise<void> {
setError(true); setError(true);
setWaiting(false); setWaiting(false);
setTimeout(() => { setTimeout(() => {
@ -17,7 +17,7 @@ export function LoginForm() {
}, 1000); }, 1000);
} }
async function loginPress(e: Event) { async function loginPress(e: Event): Promise<void> {
e.preventDefault(); e.preventDefault();
setWaiting(true); setWaiting(true);
submitLogin(username(), password()).then((token) => { submitLogin(username(), password()).then((token) => {
@ -42,7 +42,7 @@ export function LoginForm() {
placeholder="Username" placeholder="Username"
value={username()} value={username()}
class="input input-bordered" class="input input-bordered"
onChange={(e) => { onChange={(e): void => {
setUsername(e.target.value); setUsername(e.target.value);
}} }}
/> />
@ -52,14 +52,14 @@ export function LoginForm() {
placeholder="Password" placeholder="Password"
value={password()} value={password()}
class="input input-bordered" class="input input-bordered"
onChange={(e) => { onChange={(e): void => {
setPassword(e.target.value); setPassword(e.target.value);
}} }}
/> />
<button <button
class={"btn btn-primary" + (error() ? " btn-error" : "")} class={"btn btn-primary" + (error() ? " btn-error" : "")}
onClick={ loginPress } onClick={loginPress}
> >
{waiting() ? "Logging in..." : "Login"} {waiting() ? "Logging in..." : "Login"}
</button> </button>
@ -73,7 +73,7 @@ export async function submitLogin(
username: string, username: string,
password: string password: string
): Promise<string> { ): Promise<string> {
if(username == "" || password == "") return ""; if (username == "" || password == "") return "";
const response = await fetch("/api/login", { const response = await fetch("/api/login", {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },

View file

@ -1,7 +1,7 @@
import { createSignal, useContext } from "solid-js"; import { JSXElement, createSignal, useContext } from "solid-js";
import { LoginContext, ModalContext } from "../Root"; import { LoginContext, ModalContext } from "../Root";
export function RegisterForm() { export function RegisterForm(): JSXElement {
const modal_ctx = useContext(ModalContext); const modal_ctx = useContext(ModalContext);
const login_ctx = useContext(LoginContext); const login_ctx = useContext(LoginContext);
const [username, setUsername] = createSignal<string>(""); const [username, setUsername] = createSignal<string>("");
@ -10,7 +10,7 @@ export function RegisterForm() {
const [waiting, setWaiting] = createSignal(false); const [waiting, setWaiting] = createSignal(false);
const [error, setError] = createSignal(false); const [error, setError] = createSignal(false);
async function loginFailed() { async function loginFailed(): Promise<void> {
setError(true); setError(true);
setWaiting(false); setWaiting(false);
setTimeout(() => { setTimeout(() => {
@ -18,7 +18,7 @@ export function RegisterForm() {
}, 1000); }, 1000);
} }
async function regPress(e: Event) { async function regPress(e: Event): Promise<void> {
e.preventDefault(); e.preventDefault();
setWaiting(true); setWaiting(true);
submitRegistration(username(), password(), captcha()).then((token) => { submitRegistration(username(), password(), captcha()).then((token) => {
@ -43,7 +43,7 @@ export function RegisterForm() {
placeholder="Username" placeholder="Username"
value={username()} value={username()}
class="input input-bordered" class="input input-bordered"
onChange={(e) => { onChange={(e): void => {
setUsername(e.target.value); setUsername(e.target.value);
}} }}
/> />
@ -53,7 +53,7 @@ export function RegisterForm() {
placeholder="Password" placeholder="Password"
value={password()} value={password()}
class="input input-bordered" class="input input-bordered"
onChange={(e) => { onChange={(e): void => {
setPassword(e.target.value); setPassword(e.target.value);
}} }}
/> />
@ -63,7 +63,7 @@ export function RegisterForm() {
placeholder="Captcha" placeholder="Captcha"
value={password()} value={password()}
class="input input-bordered" class="input input-bordered"
onChange={(e) => { onChange={(e): void => {
setCaptcha(e.target.value); setCaptcha(e.target.value);
}} }}
/> />

View file

@ -1,4 +1,4 @@
import { Accessor, createSignal } from "solid-js"; import { Accessor, JSXElement, createSignal } from "solid-js";
import { createContext } from "solid-js"; import { createContext } from "solid-js";
import { Navbar } from "./Navbar"; import { Navbar } from "./Navbar";
@ -24,7 +24,7 @@ interface LoginContextType {
export const ModalContext = createContext<ModalContextType>(); export const ModalContext = createContext<ModalContextType>();
export const LoginContext = createContext<LoginContextType>(); export const LoginContext = createContext<LoginContextType>();
function Root() { function Root(): JSXElement {
// All of these are passed into context providers // All of these are passed into context providers
const [loginModalOpen, setLoginModalOpen] = createSignal(false); const [loginModalOpen, setLoginModalOpen] = createSignal(false);
const [token, setToken] = createSignal(""); const [token, setToken] = createSignal("");

View file

@ -1,9 +1,9 @@
import { useParams } from "@solidjs/router"; import { useParams } from "@solidjs/router";
import { Show, Suspense, createResource } from "solid-js"; import { JSXElement, Show, Suspense, createResource } from "solid-js";
import { getPost } from "./api"; import { getPost } from "./api";
import { PostSegment } from "./Posts"; import { PostSegment } from "./Posts";
export function SinglePost() { export function SinglePost(): JSXElement {
const params = useParams(); const params = useParams();
const [post] = createResource(params.postid, getPost); const [post] = createResource(params.postid, getPost);