diff --git a/app/Text/JsonTextRepository.php b/app/Text/JsonTextRepository.php
new file mode 100644
index 0000000..fc8640d
--- /dev/null
+++ b/app/Text/JsonTextRepository.php
@@ -0,0 +1,108 @@
+filePath = __DIR__.'/../../data/texts.json';
+ }
+
+ public function create(CreateTextDto $dto): Text
+ {
+ $texts = $this->readTexts();
+ $id = $this->getNextId($texts);
+
+ $text = new Text(id: $id, name: $dto->name);
+ $texts[] = ['id' => $id, 'name' => $dto->name];
+
+ $this->writeTexts($texts);
+
+ return $text;
+ }
+
+ public function find(int $id): ?Text
+ {
+ $texts = $this->readTexts();
+
+ foreach ($texts as $data) {
+ if ($data['id'] === $id) {
+ return new Text(
+ id: $data['id'],
+ name: $data['name'],
+ );
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * @return Text[]
+ */
+ public function getAll(): array
+ {
+ $texts = $this->readTexts();
+
+ return array_map(
+ function (array $data) {
+ return new Text(
+ id: $data['id'],
+ name: $data['name'],
+ );
+ },
+ $texts
+ );
+ }
+
+ /**
+ * @return array
+ */
+ private function readTexts(): array
+ {
+ if (!file_exists($this->filePath)) {
+ return [];
+ }
+
+ $content = file_get_contents($this->filePath);
+
+ return json_decode($content, true) ?? [];
+ }
+
+ /**
+ * @param array $texts
+ */
+ private function writeTexts(array $texts): void
+ {
+ file_put_contents(
+ $this->filePath,
+ json_encode($texts, JSON_PRETTY_PRINT)
+ );
+ }
+
+ /**
+ * @param array $texts
+ */
+ private function getNextId(array $texts): int
+ {
+ if (empty($texts)) {
+ return 1;
+ }
+
+ $maxId = 0;
+ foreach ($texts as $text) {
+ if ($text['id'] > $maxId) {
+ $maxId = $text['id'];
+ }
+ }
+
+ return $maxId + 1;
+ }
+}
diff --git a/app/Text/TextRepository.php b/app/Text/TextRepository.php
index a280407..d899bcf 100644
--- a/app/Text/TextRepository.php
+++ b/app/Text/TextRepository.php
@@ -10,4 +10,9 @@ interface TextRepository
public function create(CreateTextDto $dto): Text;
public function find(int $id): ?Text;
+
+ /**
+ * @return Text[]
+ */
+ public function getAll(): array;
}
diff --git a/app/View/ViewController.php b/app/View/ViewController.php
index fb46073..a9f4ccc 100644
--- a/app/View/ViewController.php
+++ b/app/View/ViewController.php
@@ -2,10 +2,15 @@
namespace App\View;
+use App\Text\TextRepository;
use Psr\Http\Message\ResponseInterface as Response;
class ViewController
{
+ public function __construct(
+ private TextRepository $textRepository,
+ ) {}
+
public function admin(Response $response): Response
{
$html = file_get_contents(__DIR__.'/../../views/templates/admin.php', true);
@@ -13,4 +18,20 @@ class ViewController
return $response;
}
+
+ public function texts(Response $response): Response
+ {
+ $texts = $this->textRepository->getAll();
+
+ $textsList = '';
+ foreach ($texts as $text) {
+ $textsList .= '
' . htmlspecialchars($text->getName()) . '';
+ }
+
+ $html = file_get_contents(__DIR__.'/../../views/templates/texts.php', true);
+ $html = str_replace('{{texts}}', $textsList, $html);
+ $response->getBody()->write($html);
+
+ return $response;
+ }
}
diff --git a/bootstrap/app.php b/bootstrap/app.php
index 1fc3b7e..5d081cd 100644
--- a/bootstrap/app.php
+++ b/bootstrap/app.php
@@ -12,5 +12,6 @@ $app = Bridge::create($container);
$app->addErrorMiddleware(true, true, true);
$app->get('/admin', [ViewController::class, 'admin']);
+$app->get('/admin/texts', [ViewController::class, 'texts']);
return $app;
diff --git a/bootstrap/container.php b/bootstrap/container.php
index 3a35c97..09a0d9a 100644
--- a/bootstrap/container.php
+++ b/bootstrap/container.php
@@ -1,9 +1,12 @@
DI\create(JsonTextRepository::class),
]);
return $container;
diff --git a/cypress/e2e/admin.cy.js b/cypress/e2e/admin.cy.js
index c277eb9..c06aece 100644
--- a/cypress/e2e/admin.cy.js
+++ b/cypress/e2e/admin.cy.js
@@ -1,7 +1,24 @@
describe('The admin page', () => {
- it('successfully loads texts', () => {
- cy.visit('/admin')
- cy.get('#newTextname').type('new text')
- cy.get('#submit').click()
+ beforeEach(() => {
+ cy.visit('/admin')
+ })
+
+ it('navigates to texts page', () => {
+ cy.get('#texts').click()
+ cy.url().should('include', '/admin/texts')
+ })
+
+ it('shows texts page with heading and form', () => {
+ cy.visit('/admin/texts')
+ cy.get('h1').should('contain', 'Texts')
+ cy.get('#newTextName').should('exist')
+ cy.get('#submit').should('exist')
+ })
+
+ it('creates a new text', () => {
+ cy.visit('/admin/texts')
+ cy.get('#newTextName').type('Test Text')
+ cy.get('#submit').click()
+ cy.contains('Test Text')
})
})
diff --git a/data/texts.json b/data/texts.json
new file mode 100644
index 0000000..fe51488
--- /dev/null
+++ b/data/texts.json
@@ -0,0 +1 @@
+[]
diff --git a/tests/Fakes/FakeTextRepository.php b/tests/Fakes/FakeTextRepository.php
index 86d3076..388e01c 100644
--- a/tests/Fakes/FakeTextRepository.php
+++ b/tests/Fakes/FakeTextRepository.php
@@ -47,4 +47,20 @@ class FakeTextRepository implements TextRepository
{
return count($this->existingTexts);
}
+
+ /**
+ * @return Text[]
+ */
+ public function getAll(): array
+ {
+ return array_map(
+ function (Text $text) {
+ return new Text(
+ id: $text->getId(),
+ name: $text->getName(),
+ );
+ },
+ $this->existingTexts
+ );
+ }
}
diff --git a/views/templates/admin.php b/views/templates/admin.php
index c027843..7f463d4 100644
--- a/views/templates/admin.php
+++ b/views/templates/admin.php
@@ -1,10 +1,9 @@
- Daily Goals
+ Daily Goals - Admin
-
-
+ Texts
diff --git a/views/templates/texts.php b/views/templates/texts.php
new file mode 100644
index 0000000..b5058ab
--- /dev/null
+++ b/views/templates/texts.php
@@ -0,0 +1,15 @@
+
+
+
+ Daily Goals - Texts
+
+
+ Texts
+ Back to Admin
+
+
+
+
+