parent
098f4b46cb
commit
11e1932120
@ -0,0 +1,53 @@
|
||||
main {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#mainDiv {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#graphDiv {
|
||||
width: 75%;
|
||||
height: 450px;
|
||||
}
|
||||
|
||||
#settings_div {
|
||||
text-align: center;
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
#tableDiv {
|
||||
padding: 0;
|
||||
overflow: auto;
|
||||
flex-basis: 75%;
|
||||
}
|
||||
|
||||
#shareDiv {
|
||||
padding: 5px;
|
||||
flex-basis: 25%;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
#secondaryDiv {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#shareUsername {
|
||||
width: 100px;
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
#shareHeader {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (max-width: 950px) {
|
||||
#mainDiv {display: block}
|
||||
#graphDiv {width: 100%;}
|
||||
#settings_div {width: 100%; display: block}
|
||||
#tableDiv {width: 100%}
|
||||
#shareDiv {width: 100%}
|
||||
#secondaryDiv {display: block}
|
||||
}
|
||||
@ -0,0 +1,159 @@
|
||||
#graphDiv {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#dataDiv {
|
||||
display: none;
|
||||
position: absolute;
|
||||
height: 35px;
|
||||
width: 70px;
|
||||
background-color: white;
|
||||
border: 1px solid lightgrey;
|
||||
padding: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#dataDiv p {
|
||||
margin: 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
#dataDiv b{
|
||||
position: center;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
#graphLegend {
|
||||
display: none;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#graphLegend div {
|
||||
display: inline;
|
||||
margin: 0 10px 0 10px;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
#settings_div{
|
||||
width: 300px;
|
||||
padding: 5px;
|
||||
background-color: var(--main);
|
||||
}
|
||||
|
||||
#settings_div h2{
|
||||
color: var(--dark);
|
||||
}
|
||||
|
||||
#shareDiv{
|
||||
width: 300px;
|
||||
padding: 5px;
|
||||
background-color: var(--side);
|
||||
}
|
||||
|
||||
#shareDiv h2{
|
||||
color: var(--dark);
|
||||
}
|
||||
|
||||
table {
|
||||
margin-top: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table, th, td {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
th, td {
|
||||
padding: 4px;
|
||||
border: 1px solid darkgrey;
|
||||
min-width: 100px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
tr:nth-child(even) td:not(.UI_remove_row){
|
||||
background-color: var(--main);
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: var(--main-dark);
|
||||
}
|
||||
|
||||
th div {
|
||||
color: var(--light);
|
||||
}
|
||||
|
||||
th input {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
[contenteditable] {
|
||||
outline: 0 solid transparent;
|
||||
}
|
||||
|
||||
#rcMenu {
|
||||
z-index: 1000;
|
||||
position: absolute;
|
||||
background-color: white;
|
||||
border: 1px solid lightgrey;
|
||||
box-shadow: 2px 2px 2px gray;
|
||||
display: none;
|
||||
margin: 0;
|
||||
width: 180px;
|
||||
}
|
||||
|
||||
#rcMenu ul{
|
||||
list-style-type: none;
|
||||
padding-left: 10px;
|
||||
width: 180px;
|
||||
}
|
||||
|
||||
#rcMenu a {
|
||||
text-decoration: none;
|
||||
border-bottom: 1px solid lightgrey;
|
||||
width: 160px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#rcMenu a:hover{
|
||||
background-color: lightgrey;
|
||||
}
|
||||
|
||||
#shareDiv {
|
||||
background-color: var(--main);
|
||||
}
|
||||
|
||||
#shareList {
|
||||
border: 1px solid var(--main-dark);
|
||||
}
|
||||
|
||||
#shareList div{
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#shareList div button{
|
||||
color: red;
|
||||
display: inline-block;
|
||||
float: right;
|
||||
height: 25px;
|
||||
margin: 0;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
#shareList div button:hover{
|
||||
background-color: var(--side);
|
||||
color: red;
|
||||
display: flex;
|
||||
transition: 300ms;
|
||||
}
|
||||
@ -0,0 +1,176 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;600;700;800&display=swap');
|
||||
|
||||
:root {
|
||||
--dark: #1E1B18;
|
||||
--light: #E3E7F1;
|
||||
--side: #E3E7F1;
|
||||
--main: #7391C8;
|
||||
--main-dark: #52688F;
|
||||
}
|
||||
|
||||
* {
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
color: var(--dark);
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: var(--main-dark);
|
||||
border: none;
|
||||
color: white;
|
||||
padding: 10px 15px;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
font-size: 16px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
header {
|
||||
display: flex;
|
||||
background-color: var(--main-dark);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
header #logo {
|
||||
text-align: center;
|
||||
flex-basis: 20%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
header nav {
|
||||
display: flex;
|
||||
flex-basis: 70%;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
header #user {
|
||||
flex-basis: 10%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
header #user a {
|
||||
flex-basis: 100%;
|
||||
text-align: center;
|
||||
background-color: var(--main);
|
||||
color: var(--dark);
|
||||
}
|
||||
|
||||
header #user a:hover {
|
||||
background-color: var(--main-dark);
|
||||
}
|
||||
|
||||
header a {
|
||||
text-decoration: none;
|
||||
color: var(--light);
|
||||
font-weight: 600;
|
||||
font-size: 1em;
|
||||
line-height: 1.4em;
|
||||
padding: 1.4em 2em;
|
||||
transition: 300ms;
|
||||
}
|
||||
|
||||
header a:hover {
|
||||
background-color: var(--main-dark);
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--light);
|
||||
}
|
||||
|
||||
main {
|
||||
height: calc(100vh - 4.2em);
|
||||
width: 100%;
|
||||
display: flex;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: var(--light);
|
||||
font-size: 1.6em;
|
||||
margin: 2em 0 0 0;
|
||||
flex-basis: 100%;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: var(--side);
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.loginDiv {
|
||||
min-width: 300px;
|
||||
width: 60%;
|
||||
margin: 50px auto;
|
||||
text-align: center;
|
||||
background-color: var(--main);
|
||||
}
|
||||
|
||||
.loginDiv .msg {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.loginDiv #logoutBtn {
|
||||
color: red;
|
||||
}
|
||||
|
||||
#myGraphs {
|
||||
width: 50%;
|
||||
height: calc(100vh - 4.2em);
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
background-color: var(--main);
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#myGraphs #createGraphBtn {
|
||||
color: limegreen;
|
||||
}
|
||||
|
||||
#myGraphList div, #sharedGraphList div{
|
||||
width: 80%;
|
||||
margin: 10px 10%;
|
||||
border: 1px solid var(--main-dark);
|
||||
padding: 5px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#myGraphList div a, #sharedGraphList div a{
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
width: 75%;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#myGraphList div button{
|
||||
color: red;
|
||||
display: inline-block;
|
||||
float: right;
|
||||
margin: 0;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#myGraphList div button:hover{
|
||||
background-color: var(--side);
|
||||
color: red;
|
||||
display: flex;
|
||||
transition: 300ms;
|
||||
}
|
||||
|
||||
#sharedGraphs {
|
||||
width: 50%;
|
||||
height: calc(100vh - 4.2em);
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
background-color: var(--side);
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#sharedGraphs h1{
|
||||
color: var(--dark);
|
||||
padding-bottom: 52px;
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Form\Model\Registration;
|
||||
use App\Form\Type\RegistrationType;
|
||||
use Doctrine\ODM\MongoDB\DocumentManager;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Redirect;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class UserController extends AbstractController
|
||||
{
|
||||
#[Route('/register', name: 'register')]
|
||||
public function registerAction(): Response
|
||||
{
|
||||
$form = $this->createForm(RegistrationType::class, new Registration());
|
||||
|
||||
return $this->render('register.html.twig', [
|
||||
'form' => $form->createView()
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/create', name: 'create')]
|
||||
public function createAction(DocumentManager $dm, Request $request)
|
||||
{
|
||||
$form = $this->createForm(RegistrationType::class, new Registration());
|
||||
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$registration = $form->getData();
|
||||
|
||||
$dm->persist($registration->getUser());
|
||||
$dm->flush();
|
||||
|
||||
return $this->redirect('/');
|
||||
}
|
||||
|
||||
return $this->render('register.html.twig', [
|
||||
'form' => $form->createView()
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace App\Document;
|
||||
|
||||
use Doctrine\Bundle\MongoDBBundle\Validator\Constraints\Unique as MongoDBUnique;
|
||||
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
#[MongoDB\Document(collection: 'charts')]
|
||||
#[MongoDB\Unique(fields: 'code')]
|
||||
class Chart
|
||||
{
|
||||
/**
|
||||
* @MongoDB\Id
|
||||
*/
|
||||
#[MongoDB\Id]
|
||||
protected string $id;
|
||||
|
||||
#[MongoDB\Field(type: 'string')]
|
||||
#[Assert\NotBlank]
|
||||
protected ?string $name = null;
|
||||
|
||||
#[MongoDB\Field(type: 'string')]
|
||||
#[Assert\NotBlank]
|
||||
protected ?string $code = null;
|
||||
|
||||
#[MongoDB\Field(type: 'object')]
|
||||
#[Assert\NotBlank]
|
||||
protected ?string $metadata = null;
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getNamel(): ?string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName(?string $name): void
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function getCode(): ?string
|
||||
{
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
public function setCode(?string $code): void
|
||||
{
|
||||
$this->code = $code;
|
||||
}
|
||||
|
||||
public function getMetadata(): ?string
|
||||
{
|
||||
return $this->metadata;
|
||||
}
|
||||
|
||||
public function setMetadata(?string $metadata): void
|
||||
{
|
||||
$this->metadata = $metadata;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace App\Document;
|
||||
|
||||
use Doctrine\Bundle\MongoDBBundle\Validator\Constraints\Unique as MongoDBUnique;
|
||||
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
#[MongoDB\Document(collection: 'users')]
|
||||
#[MongoDB\Unique(fields: 'email')]
|
||||
class User
|
||||
{
|
||||
/**
|
||||
* @MongoDB\Id
|
||||
*/
|
||||
#[MongoDB\Id]
|
||||
protected string $id;
|
||||
|
||||
#[MongoDB\Field(type: 'string')]
|
||||
#[Assert\NotBlank]
|
||||
#[Assert\Email]
|
||||
protected ?string $email = null;
|
||||
|
||||
#[MongoDB\Field(type: 'string')]
|
||||
#[Assert\NotBlank]
|
||||
protected ?string $password = null;
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getEmail(): ?string
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
public function setEmail(?string $email): void
|
||||
{
|
||||
$this->email = $email;
|
||||
}
|
||||
|
||||
public function getPassword(): ?string
|
||||
{
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
// stupid simple encryption (please don't copy it!)
|
||||
public function setPassword(?string $password): void
|
||||
{
|
||||
$this->password = sha1($password);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
// src/Form/Model/Registration.php
|
||||
namespace App\Form\Model;
|
||||
|
||||
use App\Document\User;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
class Registration
|
||||
{
|
||||
/**
|
||||
* @Assert\Type(type="App\Document\User")
|
||||
*/
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* @Assert\NotBlank()
|
||||
* @Assert\IsTrue()
|
||||
*/
|
||||
protected $termsAccepted;
|
||||
|
||||
public function setUser(User $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
public function getUser()
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function getTermsAccepted()
|
||||
{
|
||||
return $this->termsAccepted;
|
||||
}
|
||||
|
||||
public function setTermsAccepted($termsAccepted)
|
||||
{
|
||||
$this->termsAccepted = (bool) $termsAccepted;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
// src/Form/Type/RegistrationType.php
|
||||
namespace App\Form\Type;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class RegistrationType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder->add('user', UserType::class);
|
||||
$builder->add('terms', CheckboxType::class, ['property_path' => 'termsAccepted']);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
// src/Form/Type/UserType.php
|
||||
namespace App\Form\Type;
|
||||
|
||||
use App\Document\User;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\EmailType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class UserType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder->add('email', EmailType::class);
|
||||
$builder->add('password', RepeatedType::class, [
|
||||
'first_name' => 'password',
|
||||
'second_name' => 'confirm',
|
||||
'type' => PasswordType::class
|
||||
]);
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => User::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Chart;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<Chart>
|
||||
*
|
||||
* @method Chart|null find($id, $lockMode = null, $lockVersion = null)
|
||||
* @method Chart|null findOneBy(array $criteria, array $orderBy = null)
|
||||
* @method Chart[] findAll()
|
||||
* @method Chart[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||
*/
|
||||
class ChartRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, Chart::class);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return Chart[] Returns an array of Chart objects
|
||||
// */
|
||||
// public function findByExampleField($value): array
|
||||
// {
|
||||
// return $this->createQueryBuilder('c')
|
||||
// ->andWhere('c.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->orderBy('c.id', 'ASC')
|
||||
// ->setMaxResults(10)
|
||||
// ->getQuery()
|
||||
// ->getResult()
|
||||
// ;
|
||||
// }
|
||||
|
||||
// public function findOneBySomeField($value): ?Chart
|
||||
// {
|
||||
// return $this->createQueryBuilder('c')
|
||||
// ->andWhere('c.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->getQuery()
|
||||
// ->getOneOrNullResult()
|
||||
// ;
|
||||
// }
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\User;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<User>
|
||||
*
|
||||
* @method User|null find($id, $lockMode = null, $lockVersion = null)
|
||||
* @method User|null findOneBy(array $criteria, array $orderBy = null)
|
||||
* @method User[] findAll()
|
||||
* @method User[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||
*/
|
||||
class UserRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, User::class);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return User[] Returns an array of User objects
|
||||
// */
|
||||
// public function findByExampleField($value): array
|
||||
// {
|
||||
// return $this->createQueryBuilder('u')
|
||||
// ->andWhere('u.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->orderBy('u.id', 'ASC')
|
||||
// ->setMaxResults(10)
|
||||
// ->getQuery()
|
||||
// ->getResult()
|
||||
// ;
|
||||
// }
|
||||
|
||||
// public function findOneBySomeField($value): ?User
|
||||
// {
|
||||
// return $this->createQueryBuilder('u')
|
||||
// ->andWhere('u.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->getQuery()
|
||||
// ->getOneOrNullResult()
|
||||
// ;
|
||||
// }
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
<header id="mainHeader">
|
||||
<div id="logo">
|
||||
<a href="index.html">EasyCharts</a>
|
||||
</div>
|
||||
<nav>
|
||||
<a href="docs.html">Documentation</a>
|
||||
</nav>
|
||||
<div id="user">
|
||||
<a href="login.html">Login</a>
|
||||
</div>
|
||||
</header>
|
||||
@ -0,0 +1,6 @@
|
||||
{# templates/egister.html.twig #}
|
||||
{{ form_start(form, {'action': path('create'), 'method': 'POST'}) }}
|
||||
{{ form_widget(form) }}
|
||||
|
||||
<input type="submit" />
|
||||
{{ form_end(form) }}
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue