Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
7ed2e12
feat(chat): add edit message functionality
shannontey29 Aug 22, 2025
feb67db
Add user online/offline status feature
YoonYit Aug 22, 2025
a9e2107
feat: add mini modal to profile section with last seen time display
Jun1409 Aug 25, 2025
c720d21
Add edit profile link to MineProfileChat component
BajaLiau Aug 26, 2025
7bbafd6
Merge pull request #2 from Jun1409/profileModal-feature
shannontey29 Aug 27, 2025
68415ae
Merge pull request #3 from BajaLiau/editProfileLink
shannontey29 Aug 27, 2025
60047be
Merge branch 'master' into feature-user-status
shannontey29 Aug 27, 2025
c2902c9
Merge pull request #4 from YoonYit/feature-user-status
shannontey29 Aug 27, 2025
4fc921f
Merge branch 'master' into feature/edit-message
shannontey29 Aug 27, 2025
b036738
Merge pull request #5 from shannontey29/feature/edit-message
shannontey29 Aug 27, 2025
6b3eaf4
add docker and docker-compose for deployment with some changes to env…
Jun1409 Aug 30, 2025
1235b63
docker & docker-compose update
Jun1409 Sep 1, 2025
91b49f5
Merge pull request #6 from Jun1409/deployment_docker_script
Jun1409 Sep 1, 2025
0aa852b
Add build automation Makefile
YoonYit Sep 1, 2025
34a0014
Merge branch 'shannontey29:master' into build-automation
YoonYit Sep 1, 2025
32060fd
Merge pull request #7 from YoonYit/build-automation
YoonYit Sep 1, 2025
7fd8e9a
-Update composer script to run test script using composer test
BajaLiau Sep 1, 2025
f9a2a6a
Merge pull request #8 from BajaLiau/testing
shannontey29 Sep 1, 2025
1f56971
Modified Makefile and added setup.bat for build automation
YoonYit Sep 1, 2025
e76a41c
Merge branch 'shannontey29:master' into build-automation
YoonYit Sep 1, 2025
dd704c4
Merge pull request #9 from YoonYit/build-automation
YoonYit Sep 1, 2025
e0445ed
Update composer.lock with no error
YoonYit Sep 1, 2025
86535d5
Update composer.lock
YoonYit Sep 1, 2025
b36915f
Merge pull request #10 from YoonYit/update-composer-lock
YoonYit Sep 1, 2025
cab839b
Add GitHub Actions CI for Laravel + React
shannontey29 Sep 2, 2025
d4ccd42
Update CI triggers to master branch
shannontey29 Sep 2, 2025
5fec698
Fix GitHub Actions CI: override DB settings for Laravel + React
shannontey29 Sep 2, 2025
f1d2031
Add full CI workflow for Laravel + React + Socket.IO
shannontey29 Sep 2, 2025
63cc40e
Add GitHub Actions CI workflow for Laravel + React + Socket.IO
shannontey29 Sep 2, 2025
0585798
Fix hashing configuration in tests for CI
shannontey29 Sep 2, 2025
20d5e0d
Setup GitHub Actions CI for Laravel + React
shannontey29 Sep 2, 2025
bc8eff6
Add Laravel + React CI workflow with automated tests and reports
shannontey29 Sep 2, 2025
acf6525
Update to actions/upload-artifact@v4
shannontey29 Sep 2, 2025
584daab
CI Workflow
shannontey29 Sep 2, 2025
99b0d23
CI workflow
shannontey29 Sep 2, 2025
6a14366
CI Workflow
shannontey29 Sep 2, 2025
9e77789
CI Workflow
shannontey29 Sep 2, 2025
385190e
CI workflow
shannontey29 Sep 2, 2025
1981209
CI Workflow
shannontey29 Sep 2, 2025
89599a8
CI Workflow
shannontey29 Sep 2, 2025
b25ab01
CI Workflow
shannontey29 Sep 2, 2025
50a0991
CI Workflow
shannontey29 Sep 2, 2025
4fae836
CI workflow
shannontey29 Sep 2, 2025
92441cf
CI Workflow
shannontey29 Sep 2, 2025
d82e650
CI Workflow
shannontey29 Sep 2, 2025
37f1976
CI Workflow
shannontey29 Sep 2, 2025
ca38a92
CI Workflow
shannontey29 Sep 2, 2025
ed7f62b
CI Workflow
shannontey29 Sep 2, 2025
5b53617
CI Workflow
shannontey29 Sep 2, 2025
ea49909
CI Workflow
shannontey29 Sep 2, 2025
95d90f3
CI Workflow
shannontey29 Sep 2, 2025
0f9b6ac
CI workflow
shannontey29 Sep 2, 2025
7de2335
CI Workflow
shannontey29 Sep 2, 2025
244122b
CI Workflow
shannontey29 Sep 2, 2025
fc710de
CI Workflow
shannontey29 Sep 2, 2025
787ac13
CI Workflow
shannontey29 Sep 2, 2025
48d3bf5
CI workflow
shannontey29 Sep 2, 2025
611b0eb
CI workflow
shannontey29 Sep 2, 2025
a5eaa75
CI Workflow
shannontey29 Sep 2, 2025
17560c5
CI Workflow
shannontey29 Sep 2, 2025
c5b71a1
CI Workflow
shannontey29 Sep 2, 2025
3a0bd15
Laravel Chat App CI Workflow
shannontey29 Sep 2, 2025
85f8e7a
Laravel Chat App CI Workflow
shannontey29 Sep 2, 2025
bd72edf
Laravel Chat App CI Workflow
shannontey29 Sep 2, 2025
ecf2c99
Laravel Chat App CI Workflow
shannontey29 Sep 2, 2025
7dd3fa1
Laravel Chat App CI Workflow
shannontey29 Sep 2, 2025
94da923
CI Workflow
shannontey29 Sep 4, 2025
afa0a4c
Laravel Chat App CI workflow
shannontey29 Sep 5, 2025
785b188
Laravel Chat App CI Workflow
shannontey29 Sep 5, 2025
ef826df
Laravel Chat App CI Workflow
shannontey29 Sep 5, 2025
5154523
Laravel Chat App CI Workflow
shannontey29 Sep 5, 2025
4476db8
Laravel Chat App CI/CD Workflow
shannontey29 Sep 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
APP_URL=http://localhost:8000

LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
Expand Down
118 changes: 118 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
name: Laravel Chat App CI Workflow

on:
push:
branches: [master]
pull_request:
branches: [master]

jobs:
ci-laravel-chat-app:
runs-on: ubuntu-latest
services:
mysql:
image: mysql:8
env:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: laravel_chat_app
ports:
- 3306:3306
options: >-
--health-cmd="mysqladmin ping -uroot -proot"
--health-interval=10s
--health-timeout=5s
--health-retries=5

env:
APP_ENV: testing
APP_DEBUG: true
APP_URL: http://127.0.0.1
DB_CONNECTION: mysql
DB_HOST: 127.0.0.1
DB_PORT: 3306
DB_DATABASE: laravel_chat_app
DB_USERNAME: root
DB_PASSWORD: root
MAIL_MAILER: log
CACHE_DRIVER: array
SESSION_DRIVER: array
QUEUE_CONNECTION: sync
SCOUT_DRIVER: database

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up PHP 8.1
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
extensions: mbstring, bcmath, pdo_mysql, exif, pcntl, gd
coverage: pcov
- name: Set up Node.js 20
uses: actions/setup-node@v3
with:
node-version: 20

- name: Build Laravel Chat App
run: make build

- name: Upload application build artifact
uses: actions/upload-artifact@v4
with:
name: laravel-chat-app-build
path: build/chat-app.zip

- name: Wait for MySQL service
run: |
for i in {1..30}; do
if mysqladmin ping -h 127.0.0.1 -uroot -proot > /dev/null 2>&1; then
echo "MySQL is ready!"
break
fi
echo "Waiting for MySQL..."
sleep 2
done

- name: Run tests and generate JUnit report
run: |
mkdir -p storage/test-reports
php artisan test --log-junit storage/test-reports/junit.xml --coverage

- name: Upload test report artifact
uses: actions/upload-artifact@v4
with:
name: laravel-chat-app-test-report
path: storage/test-reports/junit.xml

- name: Upload code coverage artifact
uses: actions/upload-artifact@v4
with:
name: laravel-chat-app-coverage
path: coverage.txt

deploy:
runs-on: ubuntu-latest
needs: ci-laravel-chat-app
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Docker
uses: docker/setup-buildx-action@v2

- name: Log in to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Build and push Docker image
run: |
docker build -t ${{ secrets.DOCKER_USERNAME }}/laravel-chat-app:latest .
docker push ${{ secrets.DOCKER_USERNAME }}/laravel-chat-app:latest

- name: Deploy with Docker Compose v2
run: |
docker compose down
docker compose up -d --build
42 changes: 42 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
FROM php:8.2-apache

# Install system dependencies
RUN apt-get update && apt-get install -y \
libpng-dev libonig-dev libxml2-dev zip unzip git curl nodejs npm

# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd

# Set working directory
WORKDIR /var/www

# Copy app source
COPY . /var/www

# Install PHP dependencies
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \
&& composer install --no-interaction --prefer-dist --optimize-autoloader

# Install Node dependencies and build assets
RUN npm install && npm run build

# Make Apache serve from Laravel's public directory
RUN rm -rf /var/www/html && ln -s /var/www/public /var/www/html

# Ensure .env exists (for production, mount your real .env or use secrets)
RUN [ ! -f .env ] && cp .env.example .env || true

# Set permissions
RUN chown -R www-data:www-data /var/www/storage /var/www/bootstrap/cache

RUN a2enmod rewrite

RUN echo '<Directory /var/www/public>\n\
AllowOverride All\n\
Require all granted\n\
</Directory>' > /etc/apache2/conf-available/laravel.conf \
&& a2enconf laravel


EXPOSE 80
CMD ["apache2-foreground"]
23 changes: 23 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
APP_ENV=.env

install:
composer install --no-interaction --prefer-dist --ignore-platform-reqs
npm ci

setup-env:
@test -f $(APP_ENV) || cp .env.example $(APP_ENV)
php artisan key:generate

migrate:
php artisan migrate --seed --force

compile:
npm run build

package:
@mkdir -p build
zip -r build/chat-app.zip . -x "*.git*" "node_modules/*" "vendor/*" "storage/logs/*" "build/*"
@echo "Application packaged at build/chat-app.zip"

build: install setup-env migrate compile package
@echo "Build completed successfully!"
8 changes: 8 additions & 0 deletions app/Http/Controllers/Auth/AuthenticatedSessionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ public function store(LoginRequest $request): RedirectResponse

$request->session()->regenerate();

$user = $request->user();
$user->update([
'status' => 'online',
'last_seen_at' => now(),
]);


return redirect()->intended(RouteServiceProvider::HOME);
}

Expand All @@ -43,6 +50,7 @@ public function store(LoginRequest $request): RedirectResponse
public function destroy(Request $request): RedirectResponse
{
Auth::guard('web')->user()->update([
'status' => 'offline',
'last_seen_at' => now(),
]);

Expand Down
7 changes: 4 additions & 3 deletions app/Http/Controllers/Auth/RegisteredUserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ public function store(Request $request): RedirectResponse
{
$request->validate([
'name' => 'required|string|max:255',
'username' => 'required|string|max:255|alpha_num|unique:'.User::class,
'email' => 'required|string|email|max:255|unique:'.User::class,
'username' => 'required|string|max:255|alpha_num|unique:users,username',
'email' => 'required|string|email|max:255|unique:users,email',
'password' => ['required', 'confirmed', Rules\Password::defaults()],
]);

Expand All @@ -45,9 +45,10 @@ public function store(Request $request): RedirectResponse
'password' => Hash::make($request->password),
'uuid' => str()->uuid(),
'last_seen_at' => now(),
'status' => 'online',
]);

// event(new Registered($user));
event(new Registered($user));

Auth::login($user);

Expand Down
15 changes: 15 additions & 0 deletions app/Http/Controllers/ChatController.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,19 @@ private function loadMessages($user)
->values()
->toArray();
}

public function update(Chat $chat, ChatRequest $request)
{
if ($chat->sender_id !== auth()->id()) {
abort(403);
}

$chat->update([
'message' => $request->message,
]);

broadcast(new NewMessageEvent($chat->load('receiver')))->toOthers();

return back();
}
}
4 changes: 3 additions & 1 deletion app/Models/Chat.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@

class Chat extends Model
{
protected $guarded = ['id'];
use HasFactory;

protected $fillable = ['sender_id', 'receiver_id', 'message', 'reply_id', 'seen_at', 'message_deleted_at'];

protected $casts = [
'seen_at' => 'datetime',
Expand Down
1 change: 1 addition & 0 deletions app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class User extends Authenticatable
'password',
'uuid',
'last_seen_at',
'status'
];

/**
Expand Down
4 changes: 4 additions & 0 deletions app/Providers/AppServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Helpers\Helper;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;

class AppServiceProvider extends ServiceProvider
{
Expand All @@ -20,6 +21,8 @@ public function register(): void
*/
public function boot(): void
{
Schema::defaultStringLength(191);

\Broadcast::channel('online-users', function ($user) {
return [
'id' => $user->id,
Expand All @@ -28,5 +31,6 @@ public function boot(): void
'last_seen_at' => Helper::userLastActivityStatus($user->last_seen_at),
];
});
Schema::defaultStringLength(191);
}
}
Binary file added build/chat-app.zip
Binary file not shown.
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
],
"post-create-project-cmd": [
"@php artisan key:generate --ansi"
],
"test": [
"@php artisan test"
]
},
"extra": {
Expand Down
Loading