Skip to content

Commit

Permalink
HUGE
Browse files Browse the repository at this point in the history
  • Loading branch information
svenvandescheur committed May 7, 2024
1 parent bec3bb1 commit 4f47824
Show file tree
Hide file tree
Showing 15 changed files with 345 additions and 5 deletions.
2 changes: 2 additions & 0 deletions backend/src/openarchiefbeheer/conf/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
#

INSTALLED_APPS = [
"corsheaders",
"django.contrib.auth",
"django.contrib.sessions",
"django.contrib.contenttypes",
Expand Down Expand Up @@ -128,6 +129,7 @@
]

MIDDLEWARE = [
"corsheaders.middleware.CorsMiddleware",
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
# 'django.middleware.locale.LocaleMiddleware',
Expand Down
8 changes: 8 additions & 0 deletions frontend/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
120 changes: 120 additions & 0 deletions frontend/bin/create_page.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#!/bin/bash

PAGES_DIR="src/pages"
INDEX_FILE="$PAGES_DIR/index.ts"

page_name=$1
page_name_lowercase=$(echo "$page_name" | tr '[:upper:]' '[:lower:]')
capitalized_page_name=$(echo "$page_name" | awk '{print toupper(substr($0, 1, 1)) tolower(substr($0, 2))}')
page_dir="$PAGES_DIR/$page_name_lowercase"

# Function to check if a directory exists
function directory_exists() {
[ -d $1 ]
}

# Function to create a directory if it doesn't exist
function create_directory() {
if ! directory_exists $1; then
mkdir -p $1
fi
}

# Function to create the index.ts file
function create_index_file() {
echo "export * from \"./$capitalized_page_name\";" > "$2/index.ts"
}

# Function to create the CSS file
function create_css_file() {
echo ".${capitalized_page_name}Page {" > "$2/$capitalized_page_name.css"
echo " /* Rules here. */" >> "$2/$capitalized_page_name.css"
echo "}" >> "$2/$capitalized_page_name.css"
}

# Function to create the stories.tsx file
function create_stories_file() {
cat > "$2/$capitalized_page_name.stories.tsx" <<EOF
import type { Meta, StoryObj } from "@storybook/react";
import { ${capitalized_page_name}Page } from "./$capitalized_page_name";
const meta = {
title: "Pages/${capitalized_page_name}",
component: ${capitalized_page_name}Page,
} satisfies Meta<typeof ${capitalized_page_name}Page>;
export default meta;
type Story = StoryObj<typeof meta>;
export const ${page_name_lowercase}Page: Story = {
args: {
children: "The quick brown fox jumps over the lazy dog.",
},
};
EOF
}

# Function to create the page file
function create_page_file() {
cat > "$2/$capitalized_page_name.tsx" <<EOF
import React from "react";
import "./$capitalized_page_name.css";
export type ${capitalized_page_name}Props = React.ComponentProps<"main"> & {
// Props here.
};
/**
* ${capitalized_page_name} page
*/
export function ${capitalized_page_name}Page({ children, ...props }: ${capitalized_page_name}Props) {
return (
<main className="${capitalized_page_name}Page" {...props}>
{children}
</main>
);
}
EOF
}

# Function to update the index.ts file in pages
function update_index_file() {
echo "// Auto-generated file. Do not modify manually." > "$INDEX_FILE"
for page_dir in "$PAGES_DIR"/*/; do
page_name=$(basename "$page_dir")
echo "export * from \"./$page_name\";" >> "$INDEX_FILE"
done
}

# Main script

# Check if $PAGES_DIR directory exists, if not create it
create_directory $PAGES_DIR

# Check if a page name is provided
if [ -z "$1" ]; then
echo "Error: Please provide a page name."
exit 1
fi

# Check if page already exists
if directory_exists $page_dir; then
echo "Error: page '$capitalized_page_name' already exists."
exit 1
fi

# Create page directory
create_directory $page_dir

# Create individual files
create_index_file $capitalized_page_name $page_dir
create_css_file $capitalized_page_name $page_dir
create_stories_file $capitalized_page_name $page_dir
create_page_file $capitalized_page_name $page_dir

# Update pages/index.ts file
update_index_file

echo "page '$capitalized_page_name' created successfully."
5 changes: 3 additions & 2 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@maykin-ui/admin-ui": "github:maykinmedia/admin-ui",
"@maykin-ui/admin-ui": "file:../../maykin-ui/maykin-ui-admin-ui-0.0.5.tgz",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.App {
height: 100%;
}
6 changes: 6 additions & 0 deletions frontend/src/index.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
html,
body,
#root {
height: 100%;
}

body {
margin: 0;
}
35 changes: 33 additions & 2 deletions frontend/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,45 @@
import * as React from "react";
import * as ReactDOM from "react-dom/client";
import { RouterProvider, createBrowserRouter } from "react-router-dom";
import {
RouterProvider,
createBrowserRouter,
redirect,
} from "react-router-dom";

import App from "./App";
import "./index.css";
import { login } from "./lib/api/auth";
import { LoginPage } from "./pages";

const router = createBrowserRouter([
{
path: "/",
element: <div>Hello world!</div>,
element: <div>hoi</div>,
loader: () => {
// Redirect if not authenticated.
return redirect("/sign-in");
},
},
{
path: "/sign-in",
element: <LoginPage />,
action: async ({ request }) => {
const formData = await request.formData();
const username = formData.get("username");
const password = formData.get("password");

try {
const responseData = await login(
username as string,
password as string,
);
console.log(responseData);
// Redirect if login successful.
return redirect("/");
} catch (e: any) {
return e;
}
},
},
]);

Expand Down
53 changes: 53 additions & 0 deletions frontend/src/lib/api/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { createCookieString, getCookie } from "../cookie/cookie";

/** The base url for all API requests. */
export const BASE_URL = "http://localhost:8000/api/v1";

/**
* API call for authentication.
* @param username
* @param password
*/
export async function login(username: string, password: string) {
const csrfToken = getCookie("csrftoken");
console.log(csrfToken);
const response = await makeApiCall(
"POST",
"/auth/login/",
{
username,
password,
},
{
// "Set-Cookie": createCookieString("csrftoken", csrfToken || "", 365),
"Content-Type": "application/json",
"X-CSRFToken": csrfToken || "",
},
);
return response;
}

/**
* Makes an actual fetch request to the API, should be used by all other API implementations.
* @param method
* @param endpoint
* @param data
* @param headers
*/
export async function makeApiCall(
method: "POST",
endpoint: string,
data?: Record<string, unknown>,
headers?: Record<string, string>,
) {
const url = BASE_URL + endpoint;
const abortController = new AbortController();
const request = await fetch(url, {
credentials: "same-origin",
body: data ? JSON.stringify(data) : undefined,
headers,
method: method,
signal: abortController.signal,
});
return request.json();
}
48 changes: 48 additions & 0 deletions frontend/src/lib/cookie/cookie.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* Sets a cookie.
* @param name
* @param value
* @param days
*/
export function setCookie(name: string, value: string, days: number): void {
document.cookie = createCookieString(name, value, days);
}

/**
* Creates a cookie string.
* @param name
* @param value
* @param days
*/
export function createCookieString(
name: string,
value: string,
days: number,
): string {
let expires = "";
if (days) {
const date = new Date();
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
expires = "; expires=" + date.toUTCString();
}
return name + "=" + (value || "") + expires + "; path=/";
}

/**
* Gets the value of a cookie.
* @param name
*/
export function getCookie(name: string): string | null {
const nameEQ = name + "=";
const ca = document.cookie.split(";");
for (let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) === " ") {
c = c.substring(1);
}
if (c.indexOf(nameEQ) === 0) {
return c.substring(nameEQ.length, c.length);
}
}
return null;
}
2 changes: 2 additions & 0 deletions frontend/src/pages/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Auto-generated file. Do not modify manually.
export * from "./login";
3 changes: 3 additions & 0 deletions frontend/src/pages/login/Login.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.LoginPage {
/* Rules here. */
}
17 changes: 17 additions & 0 deletions frontend/src/pages/login/Login.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Meta, StoryObj } from "@storybook/react";

import { LoginPage } from "./Login";

const meta = {
title: "Pages/Login",
component: LoginPage,
} satisfies Meta<typeof LoginPage>;

export default meta;
type Story = StoryObj<typeof meta>;

export const loginPage: Story = {
args: {
children: "The quick brown fox jumps over the lazy dog.",
},
};
Loading

0 comments on commit 4f47824

Please sign in to comment.