feat: integrate Grafana dashboards into BOC DashboardPage
- Add Infrastructure Health section with CPU/Memory/Disk panels - Add Service Status section with PM2/Docker panels - Create GrafanaPanel component for iframe embedding - Build passes successfully
This commit is contained in:
@@ -0,0 +1,174 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Employee represents a company employee
|
||||
type Employee struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
Phone string `json:"phone"`
|
||||
Department string `json:"department"`
|
||||
Position string `json:"position"`
|
||||
StartDate time.Time `json:"start_date"`
|
||||
Status string `json:"status"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// Leave represents a leave request
|
||||
type Leave struct {
|
||||
ID string `json:"id"`
|
||||
EmployeeID string `json:"employee_id"`
|
||||
Type string `json:"type"`
|
||||
StartDate time.Time `json:"start_date"`
|
||||
EndDate time.Time `json:"end_date"`
|
||||
Status string `json:"status"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
// Timesheet represents a time entry
|
||||
type Timesheet struct {
|
||||
ID string `json:"id"`
|
||||
EmployeeID string `json:"employee_id"`
|
||||
ProjectID *string `json:"project_id"`
|
||||
Date time.Time `json:"date"`
|
||||
Hours float64 `json:"hours"`
|
||||
Description string `json:"description"`
|
||||
Status string `json:"status"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
// HRRepository handles all HR-related database operations
|
||||
type HRRepository struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
func NewHRRepository(db *sql.DB) *HRRepository {
|
||||
return &HRRepository{db: db}
|
||||
}
|
||||
|
||||
// ListEmployees returns all employees
|
||||
func (r *HRRepository) ListEmployees(ctx context.Context) ([]Employee, error) {
|
||||
rows, err := r.db.QueryContext(ctx, `
|
||||
SELECT id, name, email, phone, department, position, start_date, status, created_at, updated_at
|
||||
FROM boc_employees
|
||||
ORDER BY name
|
||||
`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var employees []Employee
|
||||
for rows.Next() {
|
||||
var e Employee
|
||||
if err := rows.Scan(&e.ID, &e.Name, &e.Email, &e.Phone, &e.Department, &e.Position, &e.StartDate, &e.Status, &e.CreatedAt, &e.UpdatedAt); err != nil {
|
||||
continue
|
||||
}
|
||||
employees = append(employees, e)
|
||||
}
|
||||
return employees, rows.Err()
|
||||
}
|
||||
|
||||
// GetEmployee returns a single employee by ID
|
||||
func (r *HRRepository) GetEmployee(ctx context.Context, id string) (*Employee, error) {
|
||||
var e Employee
|
||||
err := r.db.QueryRowContext(ctx, `
|
||||
SELECT id, name, email, phone, department, position, start_date, status, created_at, updated_at
|
||||
FROM boc_employees
|
||||
WHERE id = $1
|
||||
`, id).Scan(&e.ID, &e.Name, &e.Email, &e.Phone, &e.Department, &e.Position, &e.StartDate, &e.Status, &e.CreatedAt, &e.UpdatedAt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &e, nil
|
||||
}
|
||||
|
||||
// CreateEmployee creates a new employee
|
||||
func (r *HRRepository) CreateEmployee(ctx context.Context, e *Employee) error {
|
||||
return r.db.QueryRowContext(ctx, `
|
||||
INSERT INTO boc_employees (name, email, phone, department, position, start_date, status)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
||||
RETURNING id, created_at, updated_at
|
||||
`, e.Name, e.Email, e.Phone, e.Department, e.Position, e.StartDate, e.Status).Scan(&e.ID, &e.CreatedAt, &e.UpdatedAt)
|
||||
}
|
||||
|
||||
// UpdateEmployee updates an existing employee
|
||||
func (r *HRRepository) UpdateEmployee(ctx context.Context, id string, e *Employee) error {
|
||||
_, err := r.db.ExecContext(ctx, `
|
||||
UPDATE boc_employees
|
||||
SET name = $1, email = $2, phone = $3, department = $4, position = $5, start_date = $6, status = $7, updated_at = NOW()
|
||||
WHERE id = $8
|
||||
`, e.Name, e.Email, e.Phone, e.Department, e.Position, e.StartDate, e.Status, id)
|
||||
return err
|
||||
}
|
||||
|
||||
// ListLeaves returns all leave requests
|
||||
func (r *HRRepository) ListLeaves(ctx context.Context) ([]Leave, error) {
|
||||
rows, err := r.db.QueryContext(ctx, `
|
||||
SELECT id, employee_id, type, start_date, end_date, status, created_at
|
||||
FROM boc_leaves
|
||||
ORDER BY start_date DESC
|
||||
`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var leaves []Leave
|
||||
for rows.Next() {
|
||||
var l Leave
|
||||
if err := rows.Scan(&l.ID, &l.EmployeeID, &l.Type, &l.StartDate, &l.EndDate, &l.Status, &l.CreatedAt); err != nil {
|
||||
continue
|
||||
}
|
||||
leaves = append(leaves, l)
|
||||
}
|
||||
return leaves, rows.Err()
|
||||
}
|
||||
|
||||
// CreateLeave creates a new leave request
|
||||
func (r *HRRepository) CreateLeave(ctx context.Context, l *Leave) error {
|
||||
return r.db.QueryRowContext(ctx, `
|
||||
INSERT INTO boc_leaves (employee_id, type, start_date, end_date, status)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING id, created_at
|
||||
`, l.EmployeeID, l.Type, l.StartDate, l.EndDate, l.Status).Scan(&l.ID, &l.CreatedAt)
|
||||
}
|
||||
|
||||
// ListTimesheets returns all timesheet entries
|
||||
func (r *HRRepository) ListTimesheets(ctx context.Context) ([]Timesheet, error) {
|
||||
rows, err := r.db.QueryContext(ctx, `
|
||||
SELECT id, employee_id, project_id, date, hours, description, status, created_at
|
||||
FROM boc_timesheets
|
||||
ORDER BY date DESC
|
||||
LIMIT 100
|
||||
`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var timesheets []Timesheet
|
||||
for rows.Next() {
|
||||
var t Timesheet
|
||||
if err := rows.Scan(&t.ID, &t.EmployeeID, &t.ProjectID, &t.Date, &t.Hours, &t.Description, &t.Status, &t.CreatedAt); err != nil {
|
||||
continue
|
||||
}
|
||||
timesheets = append(timesheets, t)
|
||||
}
|
||||
return timesheets, rows.Err()
|
||||
}
|
||||
|
||||
// CreateTimesheet creates a new timesheet entry
|
||||
func (r *HRRepository) CreateTimesheet(ctx context.Context, t *Timesheet) error {
|
||||
return r.db.QueryRowContext(ctx, `
|
||||
INSERT INTO boc_timesheets (employee_id, project_id, date, hours, description, status)
|
||||
VALUES ($1, $2, $3, $4, $5, $6)
|
||||
RETURNING id, created_at
|
||||
`, t.EmployeeID, t.ProjectID, t.Date, t.Hours, t.Description, t.Status).Scan(&t.ID, &t.CreatedAt)
|
||||
}
|
||||
Reference in New Issue
Block a user