From ad0ace3b5ceb26dd1687e2305936a2657dc757f4 Mon Sep 17 00:00:00 2001 From: nachpm Date: Tue, 21 Oct 2025 12:54:33 +0200 Subject: [PATCH] Implement post fetching and pagination for Test 1. --- controllers/SiteController.php | 19 ++++++- models/Post.php | 85 ++++++++++++++++++++++++++++ views/site/test1.php | 62 +++++++++++++++++++- web/css/site.css | 100 +++++++++++++++++++++++++++++++++ 4 files changed, 264 insertions(+), 2 deletions(-) create mode 100644 models/Post.php diff --git a/controllers/SiteController.php b/controllers/SiteController.php index 54a70f1..3e9e653 100644 --- a/controllers/SiteController.php +++ b/controllers/SiteController.php @@ -3,6 +3,7 @@ namespace app\controllers; use yii\web\Controller; +use app\models\Post; class SiteController extends Controller{ /** @@ -31,6 +32,22 @@ public function actionIndex(){ * @return string */ public function actionTest1(){ - return $this->render('test1'); + $result = Post::getPaginatedPosts(6); + $error = null; + $posts = []; + $pagination = null; + + if ($result === false) { + $error = 'Error loading posts from API. Please try again later.'; + } else { + $posts = $result['posts']; + $pagination = $result['pagination']; + } + + return $this->render('test1', [ + 'posts' => $posts, + 'pagination' => $pagination, + 'error' => $error + ]); } } diff --git a/models/Post.php b/models/Post.php new file mode 100644 index 0000000..0319df4 --- /dev/null +++ b/models/Post.php @@ -0,0 +1,85 @@ + [ + 'timeout' => 10, + 'method' => 'GET', + 'header' => 'Content-Type: application/json' + ] + ]); + + $response = @file_get_contents($url, false, $context); + + if ($response === false) { + return false; + } + + $data = json_decode($response, true); + + if (json_last_error() !== JSON_ERROR_NONE) { + return false; + } + + $posts = []; + foreach ($data as $item) { + $post = new self(); + $post->id = $item['id']; + $post->userId = $item['userId']; + $post->title = $item['title']; + $post->body = $item['body']; + $posts[] = $post; + } + + return $posts; + } + + /** + * Get paginated posts + * @param int $pageSize + * @return array|false + */ + public static function getPaginatedPosts($pageSize = 6) + { + $allPosts = self::fetchPosts(); + + if ($allPosts === false) { + return false; + } + + $pagination = new Pagination([ + 'totalCount' => count($allPosts), + 'pageSize' => $pageSize, + 'pageSizeParam' => false, + 'forcePageParam' => false, + ]); + + $offset = $pagination->offset; + $limit = $pagination->limit; + $posts = array_slice($allPosts, $offset, $limit); + + return [ + 'posts' => $posts, + 'pagination' => $pagination + ]; + } +} diff --git a/views/site/test1.php b/views/site/test1.php index d08b3e3..f2308a2 100644 --- a/views/site/test1.php +++ b/views/site/test1.php @@ -27,7 +27,67 @@
-

Posts

+
+

Posts

+ + + + + + +
+ +
+
+
+
title ?>
+

body ?>

+
+ +
+
+ +
+ + pageCount > 1): ?> +
+
+ + +
+ + Showing offset + 1 ?> - offset + $pagination->limit, $pagination->totalCount) ?> + of totalCount ?> posts + +
+
+
+ + + + +
diff --git a/web/css/site.css b/web/css/site.css index 9b92ad0..d09223b 100644 --- a/web/css/site.css +++ b/web/css/site.css @@ -28,3 +28,103 @@ main > .container { margin-top: 5px; color: #999; } + +.posts-list .card { + transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out; + border: 1px solid #e0e0e0; +} + +.posts-list .card:hover { + transform: translateY(-2px); + box-shadow: 0 4px 8px rgba(0,0,0,0.1); +} + +.posts-list .card-title { + font-size: 1.1rem; + font-weight: 600; + color: #333; + margin-bottom: 0.75rem; + line-height: 1.3; +} + +.posts-list .card-text { + color: #666; + font-size: 0.9rem; + line-height: 1.4; + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.posts-list .card-footer { + background-color: #f8f9fa; + border-top: 1px solid #e0e0e0; + padding: 0.75rem 1rem; +} + +.posts-list .text-muted { + font-size: 0.8rem; +} + +.site-test1 h2 { + color: #2c3e50; + margin-bottom: 1.5rem; + border-bottom: 2px solid #3498db; + padding-bottom: 0.5rem; +} + +.site-test1 .alert { + margin-bottom: 1.5rem; +} + +.pagination { + margin-bottom: 0; +} + +.pagination .page-item .page-link { + color: #3498db; + border: 1px solid #dee2e6; + padding: 0.5rem 0.75rem; + margin: 0 2px; + border-radius: 4px; + transition: all 0.2s ease-in-out; +} + +.pagination .page-item .page-link:hover { + color: #2c3e50; + background-color: #e9ecef; + border-color: #3498db; + transform: translateY(-1px); +} + +.pagination .page-item.active .page-link { + background-color: #3498db; + border-color: #3498db; + color: white; +} + +.pagination .page-item.disabled .page-link { + color: #6c757d; + background-color: #fff; + border-color: #dee2e6; + cursor: not-allowed; +} + +.pagination .page-item.disabled .page-link:hover { + transform: none; + background-color: #fff; + border-color: #dee2e6; +} + +.pagination-info { + color: #6c757d; + font-size: 0.9rem; +} + +.pagination-info small { + background-color: #f8f9fa; + padding: 0.25rem 0.5rem; + border-radius: 3px; + border: 1px solid #e9ecef; +}