Static Project page done. Activity & Files tabs added. Preloader added. Changed History to Activity

This commit is contained in:
Ruidy Nemausat 2020-02-20 14:16:02 +01:00
parent b861a65892
commit 0990e59d64
18 changed files with 288 additions and 16 deletions

View file

@ -44,3 +44,4 @@
- update assignments automatically from context
- use PATCH instead of PUT
- logging
- check useRef, useReducer, dispatch

View file

@ -0,0 +1,35 @@
import React, { FC } from "react";
import { Activity } from "../types/Activity";
type IProps = {
activities: Activity[];
};
export const ActivityCollection: FC<IProps> = ({ activities }) => {
return (
<>
<ul className="collection">
{activities.map((f: Activity) => (
<ActivityEntry activity={f} />
))}
</ul>
</>
);
};
type IFProps = {
activity: Activity;
};
export const ActivityEntry: FC<IFProps> = ({ activity }) => {
return (
<li key={activity.id} className="collection-item avatar">
<img src={activity.user.picture} alt="" className="circle" />
{/* <i className="material-icons circle">folder</i> */}
<span className="title">
{activity.user.firstName} {activity.description} {activity.ticket.title}
</span>
<p>{activity.date.toDateString()}</p>
</li>
);
};

View file

@ -0,0 +1,20 @@
import React, { FC } from "react";
import { FloatingButton } from "./FloatingButton";
import { ActivityCollection } from "./ActivityCollection";
import { Activity } from "../types/Activity";
type IProps = {
activities: Activity[];
};
export const ActivityList: FC<IProps> = ({ activities }) => {
return (
<>
<div className="row valign-wrapper">
<h3>Activity</h3>
<FloatingButton color=" blue-grey lighten-4" size="" />
</div>
<ActivityCollection activities={activities} />
</>
);
};

View file

@ -0,0 +1,22 @@
import React, { FC } from "react";
import { AppFile } from "../types/AppFile";
import { FloatingButton } from "./FloatingButton";
import { FileCollection } from "./FileCollection";
import { DropZone } from "./DropZone";
type IProps = {
files: AppFile[];
};
export const FileList: FC<IProps> = ({ files }) => {
return (
<>
<div className="row valign-wrapper">
<h3>Files</h3>
<FloatingButton color=" blue-grey lighten-4" size="" />
</div>
<DropZone />
<FileCollection files={files} />
</>
);
};

View file

@ -0,0 +1,7 @@
import React, { FC } from "react";
type IProps = {};
export const DropZone: FC<IProps> = () => {
return <div className="copy">Drag & Drop your files here.</div>;
};

View file

@ -0,0 +1,38 @@
import React, { FC } from "react";
import { AppFile } from "../types/AppFile";
type IProps = {
files: AppFile[];
};
export const FileCollection: FC<IProps> = ({ files }) => {
return (
<>
<ul className="collection">
{files.map((f: AppFile) => (
<FileEntry file={f} />
))}
</ul>
</>
);
};
type IFProps = {
file: AppFile;
};
export const FileEntry: FC<IFProps> = ({ file }) => {
return (
<li key={file.id} className="collection-item avatar">
{/* <img src={require("../images/user_1.jpg")} alt="" className="circle" /> */}
<i className="material-icons circle">folder</i>
<span className="title">{file.name}</span>
<p>
{file.size}kb {file.format}
</p>
<a href="#!" className="secondary-content">
<i className="material-icons">more_vert</i>
</a>
</li>
);
};

View file

@ -0,0 +1,55 @@
import React, { FC } from "react";
export const Preloader: FC = () => {
return (
<div className="preloader-wrapper big active">
<div className="spinner-layer spinner-blue">
<div className="circle-clipper left">
<div className="circle"></div>
</div>
<div className="gap-patch">
<div className="circle"></div>
</div>
<div className="circle-clipper right">
<div className="circle"></div>
</div>
</div>
<div className="spinner-layer spinner-red">
<div className="circle-clipper left">
<div className="circle"></div>
</div>
<div className="gap-patch">
<div className="circle"></div>
</div>
<div className="circle-clipper right">
<div className="circle"></div>
</div>
</div>
<div className="spinner-layer spinner-yellow">
<div className="circle-clipper left">
<div className="circle"></div>
</div>
<div className="gap-patch">
<div className="circle"></div>
</div>
<div className="circle-clipper right">
<div className="circle"></div>
</div>
</div>
<div className="spinner-layer spinner-green">
<div className="circle-clipper left">
<div className="circle"></div>
</div>
<div className="gap-patch">
<div className="circle"></div>
</div>
<div className="circle-clipper right">
<div className="circle"></div>
</div>
</div>
</div>
);
};

View file

@ -1,16 +1,28 @@
import React, { FC } from "react";
import { TabRouterHeader } from "./TabRouterHeader";
import { TicketList } from "./TicketList";
import { FileList } from "./AppFileList";
import { Ticket } from "../types/Ticket";
import { AppFile } from "../types/AppFile";
import { Switch, Route, useRouteMatch, Redirect } from "react-router-dom";
import { ActivityList } from "./ActivityList";
import { Activity } from "../types/Activity";
interface IProps {
tickets: Ticket[];
remainingDays?: number;
tabNames: string[];
files: AppFile[];
activities: Activity[];
}
export const TabRouter: FC<IProps> = ({ tickets, remainingDays, tabNames }) => {
export const TabRouter: FC<IProps> = ({
tickets,
remainingDays,
tabNames,
files,
activities
}) => {
const { url } = useRouteMatch();
return (
<>
@ -25,11 +37,11 @@ export const TabRouter: FC<IProps> = ({ tickets, remainingDays, tabNames }) => {
</Route>
<Route path={`${url}/files`}>
{/* <TicketList tickets={tickets} /> */}
<FileList files={files} />
</Route>
<Route path={`${url}/activity`}>
{/* <TicketList tickets={tickets} /> */}
<ActivityList activities={activities} />
</Route>
</div>
</Switch>

View file

@ -12,7 +12,7 @@ export const TabRouterHeader: FC<IProps> = ({
nTabs,
tabNames
}) => {
const [isActive, setIsActive] = useState(0);
const [isActive, setIsActive] = useState<number>(0);
return (
<>

File diff suppressed because one or more lines are too long

View file

@ -18,7 +18,9 @@ export const ProjectPage: FC<IProps> = ({ viewModel }) => {
tickets,
ticketsDone,
ticketsTotalCount,
remainingDays
remainingDays,
files,
activities
} = viewModel;
const tabNames: string[] = ["Tickets", "Files", "Activity"];
return (
@ -38,7 +40,9 @@ export const ProjectPage: FC<IProps> = ({ viewModel }) => {
<TabRouter
tabNames={tabNames}
tickets={tickets}
files={files}
remainingDays={remainingDays}
activities={activities}
/>
</div>
</div>

View file

@ -0,0 +1,10 @@
import { User } from "./User";
import { Ticket } from "./Ticket";
export interface Activity {
id: number;
description: string;
date: Date;
user: User;
ticket: Ticket;
}

View file

@ -0,0 +1,9 @@
import { User } from "./User";
export interface AppFile {
id: number;
name: string;
description: string;
format: string;
size: number;
}

View file

@ -1,3 +0,0 @@
export interface File {
Id: number;
}

View file

@ -1,3 +0,0 @@
export interface History {
Id: number;
}

View file

@ -1,5 +1,7 @@
import { Ticket } from "./Ticket";
import { User } from "./User";
import { AppFile } from "./AppFile";
import { Activity } from "./Activity";
export interface Project {
id: number;
@ -9,4 +11,6 @@ export interface Project {
tickets: Ticket[];
users: User[];
plannedEnding: string;
files: AppFile[];
activities: Activity[];
}

View file

@ -1,4 +1,5 @@
export interface User {
id: string;
picture: string;
firstName: string;
}

View file

@ -2,6 +2,8 @@ import { Ticket } from "../types/Ticket";
import { Project } from "../types/Project";
import { Constants } from "../utils/Constants";
import { User } from "../types/User";
import { AppFile } from "../types/AppFile";
import { Activity } from "../types/Activity";
export default class ProjectVM {
public id: number;
@ -13,6 +15,8 @@ export default class ProjectVM {
public ticketsTotalCount: number;
public ticketsDone: number;
public remainingDays: number;
public files: AppFile[];
public activities: Activity[];
/**
* getMembers
@ -34,13 +38,14 @@ export default class ProjectVM {
this.tickets = project.tickets;
this.ticketsTotalCount = this.tickets.length;
this.ticketsDone = this.tickets.filter(t => t.status === "Done").length;
this.files = project.files;
this.activities = project.activities;
let endingDate: Date = new Date(project.plannedEnding);
let today: Date = new Date();
let plannedEnding: number = Math.abs(
endingDate.getDate() - today.getDate()
);
this.remainingDays = plannedEnding;
}
}