MVVM architecture skeleton

This commit is contained in:
Ruidy Nemausat 2020-02-07 13:07:28 +01:00
parent 8000622416
commit d8a792efb0
18 changed files with 162 additions and 45 deletions

View file

@ -0,0 +1,15 @@
import React, { FC } from "react";
type AvatarListProps = {
avatars: string[];
};
export const AvatarList: FC<AvatarListProps> = ({ avatars }) => {
return (
<div className="row">
{avatars.map((avatar: string) => (
<img className="circle" src={avatar} width="50vh" height="50vh" />
))}
</div>
);
};

View file

@ -0,0 +1,18 @@
import React, { FC } from "react";
type HeaderProps = {
title: string;
description: string;
};
export const Header: FC<HeaderProps> = ({
title,
description
}) => {
return (
<>
<h2>{title}</h2>
<h4>{description}</h4>
</>
);
};

View file

@ -0,0 +1,17 @@
import React, { FC } from "react";
type ProgressBarProps = {
value?: number;
max?: number;
};
export const ProgressBar: FC<ProgressBarProps> = ({
value = 60,
max = 100
}) => {
return (
<div className="row">
<progress value={value} max={max}></progress>
</div>
);
};

View file

@ -0,0 +1,22 @@
import React, { FC } from "react";
import { Ticket } from "../types/Ticket";
type TicketListProps = {
tickets?: Ticket[];
};
export const TicketList: FC<TicketListProps> = ({
tickets = [
{ Id: 1, Title: "Todo today" },
{ Id: 2, Title: "Todo tomorrow" },
{ Id: 5, Title: "Todo NOW!!!" }
]
}) => {
return (
<div className="row">
{tickets.map((t: Ticket) => (
<li key={t.Id}>{t.Title}</li>
))}
</div>
);
};

View file

@ -0,0 +1,6 @@
import React, { FC } from "react";
import { HomePage } from "../pages/HomePage";
export const HomeController: FC = () => {
return <HomePage />;
};

View file

@ -0,0 +1,6 @@
import React, { FC } from "react";
import { ProjectPage } from "../pages/ProjectPage";
export const ProjectController: FC = () => {
return <ProjectPage />;
};

View file

@ -0,0 +1,6 @@
import React, { FC } from "react";
import { TicketPage } from "../pages/TicketPage";
export const TicketController: FC = () => {
return <TicketPage />;
};

View file

@ -0,0 +1,6 @@
import React, { FC } from "react";
import { UserPage } from "../pages/UserPage";
export const UserController: FC = () => {
return <UserPage />;
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,005 KiB

View file

@ -1,14 +1,27 @@
import React, { FC } from "react";
import { Header } from "../components/Header";
import { AvatarList } from "../components/AvatarList";
import { ProgressBar } from "../components/ProgressBar";
import { TicketList } from "../components/TicketList";
export const ProjectPage: FC = () => {
return(
<Header />
<AvatarList />
<ProgressBar/>
<TabView>
<ChildTicket/>
<ChildFile/>
<ChildActivity/>
</TabView>
)
}
return (
<div className="section">
<div className="container">
<Header title = "Brand Concept and Design" description = "Research, ideate and present brand concepts for client consideration"/>
<AvatarList
avatars={[
"data:image/jpeg;base64,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",
"data:image/jpeg;base64,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"
]}
/>
<ProgressBar />
{/* <TabView> */}
<TicketList />
{/* <ChildFile />
<ChildActivity /> */}
{/* </TabView> */}
</div>
</div>
);
};

View file

@ -1,15 +1,20 @@
import React, { FC } from "react";
import { Header } from "../components/Header";
import { AvatarList } from "../components/AvatarList";
import { ProgressBar } from "../components/ProgressBar";
export const TicketPage: FC = () => {
return(
<Header />
<AvatarList />
<ProgressBar/>
<TabView>
<ChildTicket/>
<ChildFile/>
<ChildActivity/>
</TabView>
<Notes/>
)
}
return (
<>
<Header description = "Research, ideate and present brand concepts for client consideration" title = "Brand Concept and Design"/>
<AvatarList avatars={["../images/user_1.jpg", "../images/user_2.jpg"]} />
<ProgressBar />
{/* // <TabView>
// <ChildTicket/>
// <ChildFile/>
// <ChildActivity/>
// </TabView>
// <Notes/> */}
</>
);
};

View file

@ -1,11 +1,12 @@
import React, { FC } from "react";
import { Header } from "../components/Header";
export const UserPage: FC = () => {
return(
<Header />
<TabView>
<CardList>
<CardList>
</TabView>
)
}
return (
<Header />
// <TabView>
// <CardList>
// <CardList>
// </TabView>
);
};

View file

@ -1,3 +1,4 @@
export interface Ticket {
Id: number;
Title: string;
}

View file

@ -1,10 +1,11 @@
import React from "react";
import { Router, Route, Switch, Link, NavLink } from "react-router-dom";
import * as creacteHistory from "history";
import { HomePage } from "../pages/HomePage";
import { UserPage } from "../pages/UserPage";
import { ProjectPage } from "../pages/ProjectPage";
import { TicketPage } from "../pages/TicketPage";
import { HomeController } from "../controllers/HomeController";
import { ProjectController } from "../controllers/ProjectController";
import { UserController } from "../controllers/UserController";
import { TicketController } from "../controllers/TicketController";
export const history = creacteHistory.createBrowserHistory();
@ -13,18 +14,18 @@ export const AppRouter = () => {
<Router history={history}>
<div>
<Switch>
<Route path="/">
<HomePage />
{/* <Route path="/">
<HomeController />
</Route>
<Route path="/users/:id">
<UserPage />
</Route>
<UserController />
</Route> */}
<Route path="/projects/:id">
<ProjectPage />
</Route>
<Route path="/tickets/:id">
<TicketPage />
<ProjectController />
</Route>
{/* <Route path="/tickets/:id">
<TicketController />
</Route> */}
</Switch>
</div>
</Router>

View file

@ -1,5 +1,5 @@
export class ProjectVM {
public Id: number;
public Id?: number;
public constructor() {}
}

View file

@ -1,5 +1,5 @@
export class TicketVM {
public Id: number;
public Id?: number;
public constructor() {}
}

View file

@ -1,5 +1,5 @@
export class UserVM {
public Id: number;
public Id?: number;
public constructor() {}
}