File manager frontend
This commit is contained in:
+2
-2
@@ -2,7 +2,7 @@ import type { Component } from 'solid-js';
|
||||
|
||||
import logo from './assets/logo.svg';
|
||||
import styles from './css/App.module.css';
|
||||
import { FetchedDates } from './FetchedDates';
|
||||
import { FileManager } from './fileManager/FileManager';
|
||||
|
||||
console.log("env:", import.meta.env.MODE);
|
||||
console.log("api host:", import.meta.env.VITE_API_HOST);
|
||||
@@ -10,8 +10,8 @@ console.log("api host:", import.meta.env.VITE_API_HOST);
|
||||
const App: Component = () => {
|
||||
return (
|
||||
<div class={styles.App}>
|
||||
<FileManager />
|
||||
<header class={styles.header}>
|
||||
<FetchedDates />
|
||||
<img src={logo} class={styles.logo} alt="logo" />
|
||||
<p>
|
||||
Weather tool web
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
import { createResource } from "solid-js";
|
||||
|
||||
const apiHost = import.meta.env.VITE_API_HOST;
|
||||
|
||||
export function FetchedDates() {
|
||||
const fetchDates = async () => {
|
||||
const response = await fetch(`${apiHost}/api/show/all_dates`);
|
||||
const json = await response.json();
|
||||
return json;
|
||||
}
|
||||
|
||||
const [datesResource] = createResource(fetchDates);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{ datesResource.loading && (
|
||||
<div>Loading dates</div>
|
||||
)}
|
||||
{ datesResource.error && (
|
||||
<div>Error while loading dates: ${datesResource.error}</div>
|
||||
)}
|
||||
{ datesResource() && (
|
||||
<ul>
|
||||
{ (datesResource() as any).map((date: any) => item(date))}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function item(date: any) {
|
||||
return (
|
||||
<li>{date}</li>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export const apiHost = import.meta.env.VITE_API_HOST;
|
||||
@@ -0,0 +1,22 @@
|
||||
.container {
|
||||
display: flex;
|
||||
height: 100vh; /* Adjust to desired height */
|
||||
}
|
||||
|
||||
.column {
|
||||
flex: 1;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.column:nth-child(1),
|
||||
.column:nth-child(2) {
|
||||
flex-basis: 15%;
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
.column:nth-child(3) {
|
||||
flex-basis: 70%;
|
||||
background-color: #e6e6e6;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
.spinner {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
.spinner:after {
|
||||
content: " ";
|
||||
display: block;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
margin: 0px;
|
||||
border-radius: 50%;
|
||||
border: 6px solid #333;
|
||||
border-color: #333 transparent #333 transparent;
|
||||
animation: spinner 1.2s linear infinite;
|
||||
}
|
||||
@keyframes spinner {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { Component, createResource, Setter } from "solid-js";
|
||||
import { apiHost } from "../consts";
|
||||
|
||||
import "../css/spinner.css";
|
||||
|
||||
export const DateList: Component<{setDate: Setter<string>;}> = (props) => {
|
||||
const fetchDates = async () => {
|
||||
await new Promise(resolve => setTimeout(resolve, 500))
|
||||
const response = await fetch(`${apiHost}/api/show/all_dates`);
|
||||
const json = await response.json();
|
||||
return json;
|
||||
}
|
||||
|
||||
const [datesResource] = createResource(fetchDates);
|
||||
|
||||
const clickDate = (date: string) => {
|
||||
console.log("setDate", date);
|
||||
props.setDate(date);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{ datesResource.loading && (
|
||||
<div>
|
||||
<span class="spinner"></span>
|
||||
<span style={{ "padding-left": "16px" }}>Loading dates</span>
|
||||
</div>
|
||||
)}
|
||||
{ datesResource.error && (
|
||||
<div>Error while loading dates: ${datesResource.error}</div>
|
||||
)}
|
||||
{ datesResource() && (
|
||||
<ul>
|
||||
{ (datesResource() as any).map((date: any) =>
|
||||
<li onClick={() => clickDate(date)}>{date}</li>
|
||||
)}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { Accessor, Component, createResource, JSXElement } from "solid-js";
|
||||
import { apiHost } from "../consts";
|
||||
|
||||
export const FileContent: Component<{getFileName: Accessor<string>}> = (props) => {
|
||||
const fetchFileContent = async (fileName: string) => {
|
||||
if (fileName === "") return;
|
||||
await new Promise(resolve => setTimeout(resolve, 500))
|
||||
const response = await fetch(`${apiHost}/api/show/file/${fileName}`);
|
||||
const text = await response.text();
|
||||
return text;
|
||||
}
|
||||
|
||||
const [contentResource] = createResource(props.getFileName, fetchFileContent);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{ contentResource.loading && (
|
||||
<div>
|
||||
<span class="spinner"></span>
|
||||
<span style={{ "padding-left": "16px" }}>load content</span>
|
||||
</div>
|
||||
)}
|
||||
{ contentResource.error && (
|
||||
<div>Error while loading file content: ${contentResource.error}</div>
|
||||
)}
|
||||
{ contentResource() && (
|
||||
<div>{splitLines(contentResource())}</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function splitLines(str?: string): JSXElement {
|
||||
const lines = str?.split("<br/>") ?? ["empty..."]
|
||||
return lines.map(line =>
|
||||
<div>{line}</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { createSignal } from "solid-js";
|
||||
import "../css/FileManager.css"
|
||||
import { DateList } from "./DateList";
|
||||
import { FileContent } from "./FileContent";
|
||||
import { FileNameList } from "./FileNameList";
|
||||
|
||||
export function FileManager() {
|
||||
const [getDate, setDate] = createSignal("");
|
||||
const [getFileName, setFileName] = createSignal("");
|
||||
|
||||
return (
|
||||
<div class="fileManager">
|
||||
<h2>File manager</h2>
|
||||
<div class="container">
|
||||
<div class="column">
|
||||
<DateList setDate={setDate} />
|
||||
</div>
|
||||
<div class="column">
|
||||
<h3>{getDate()}</h3>
|
||||
<FileNameList getDate={getDate} setFileName={setFileName} />
|
||||
</div>
|
||||
<div class="column">
|
||||
<h3>{getFileName()}</h3>
|
||||
<FileContent getFileName={getFileName} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import { Accessor, Component, createResource, Setter } from "solid-js";
|
||||
import { apiHost } from "../consts";
|
||||
|
||||
import "../css/spinner.css";
|
||||
|
||||
export const FileNameList: Component<{
|
||||
getDate: Accessor<string>,
|
||||
setFileName: Setter<string>,
|
||||
}> = (props) => {
|
||||
const fetchFileNames = async (date: string) => {
|
||||
if (props.getDate() === "") return;
|
||||
await new Promise(resolve => setTimeout(resolve, 500))
|
||||
const response = await fetch(`${apiHost}/api/show/date/${date.replace(/-/g, "")}`);
|
||||
const json = await response.json();
|
||||
return json;
|
||||
}
|
||||
|
||||
const [fileNameResource] = createResource(props.getDate, fetchFileNames);
|
||||
|
||||
function clickFileName(fileName: string) {
|
||||
console.log(fileName);
|
||||
props.setFileName(fileName);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{ fileNameResource.loading && (
|
||||
<div>
|
||||
<span class="spinner"></span>
|
||||
<span style={{ "padding-left": "16px" }}>loading {props.getDate()}</span>
|
||||
</div>
|
||||
)}
|
||||
{ fileNameResource.error && (
|
||||
<div>Error while loading file names: ${fileNameResource.error}</div>
|
||||
)}
|
||||
{ fileNameResource() && (
|
||||
<ul>
|
||||
{ (fileNameResource() as any).map((fileName: any) =>
|
||||
<li onClick={() => clickFileName(fileName)}>{fileName}</li>
|
||||
)}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
return <div>yoyoyoy</div>
|
||||
}
|
||||
Reference in New Issue
Block a user