Title: Ndizi Project Management
Author: George Stephanis
Published: <strong>December 16, 2010</strong>
Last modified: June 18, 2026

---

Search plugins

![](https://s.w.org/plugins/geopattern-icon/ndizi-project-management.svg)

# Ndizi Project Management

 By [George Stephanis](https://profiles.wordpress.org/georgestephanis/)

[Download](https://downloads.wordpress.org/plugin/ndizi-project-management.1.0.2.zip)

[Live Preview](https://wordpress.org/plugins/ndizi-project-management/?preview=1)

 * [Details](https://wordpress.org/plugins/ndizi-project-management/#description)
 * [Reviews](https://wordpress.org/plugins/ndizi-project-management/#reviews)
 *  [Installation](https://wordpress.org/plugins/ndizi-project-management/#installation)
 * [Development](https://wordpress.org/plugins/ndizi-project-management/#developers)

 [Support](https://wordpress.org/support/plugin/ndizi-project-management/)

## Description

**Ndizi Project Management** is a professional, native WordPress system built for
freelancers, designers, and small agencies to coordinate client work, manage tasks,
record project hours, and generate invoices—all inside a single WordPress environment.

**Source & development:** The full, human-readable source (including the uncompressed`
src/` for every compiled asset) lives on GitHub at [github.com/georgestephanis/plugins](https://github.com/georgestephanis/plugins/tree/main/ndizi-project-management#readme).

Decoupling high-frequency data from standard WordPress posts storage, Ndizi records
all time logs in a dedicated custom SQL table (`wp_ndizi_time_entries`). This architectural
choice keeps your database queries fast and completely avoids `wp_posts` and `wp_postmeta`
database inflation.

### Key Features

 * **Premium Dashboards**: Interactive, responsive HTML/CSS dashboards for managers
   to analyze team time allocations, billable totals, and project status.
 * **Gantt Timelines**: Custom CSS Grid and SVG-based Gantt charts directly in your
   admin dashboard to visualize project schedules — no third-party chart library
   required.
 * **Decoupled Time Tracker**: Start, stop, and log timesheets directly in the admin
   bar, meta boxes, or standalone pages. Projects are neatly grouped by client, 
   and input modes are gated (either/or) to prevent conflicts.
 * **Standalone PWA Companion App**: A distraction-free companion tracking page 
   stripped of WordPress admin menus/bars. Chrome-installable as a borderless desktop
   application featuring a dark glassmorphic interface, a ticking digital clock,
   and today’s logged entry feed. Fully responsive at small-screen widths. Supports
   a `?desc=` URL parameter to pre-fill the description input (used by the Chrome
   extension). Requests browser notification permission and fires a push notification
   when the active timer exceeds 8 hours.
 * **Idle Warning Banner**: When an active timer has been running for more than 
   8 hours, a warning banner appears in the admin bar panel and on the standalone
   tracker page prompting the user to verify their logged time.
 * **Lock Date / Time Entry Locking**: Configure a lock date on the Settings page
   to prevent creating, editing, or deleting any time entry dated on or before that
   date. Protects closed billing periods from accidental modification — enforced
   across the REST API, the DB layer, and the admin UI.
 * **Customizable Tracker Icons**: A settings dashboard allowing users to select
   and dynamically render their preferred tracker icon (Banana, Clock, Punch Clock,
   Hourglass).
 * **Hierarchical Billing Rates**: Billing rates are resolved in priority order —
   task override then user default then project default — at invoice and report 
   generation time. An explicit rate of 0.00 at any level is honored for pro-bono
   entries.
 * **Date-Range Filtered Reports**: The Reports dashboard supports start date / 
   end date, project, and team member filters with bookmarkable URLs. KPI cards 
   surface total hours, billable hours, revenue, estimated salary cost, and profit
   margin.
 * **Invoice Generation & Exports**: Automatically aggregate un-invoiced billable
   hours into detailed project invoices. Export invoice line items to CSV or JSON
   formats, or print/save them using a clean, professional print stylesheet.
 * **QuickBooks CSV Export**: Export filtered time report data as a QuickBooks-compatible
   CSV file (Customer, Item, Date, Hours, Rate, Description) for direct import into
   accounting software.
 * **Glassmorphic Client Portal**: A premium front-end experience available as the`[
   ndizi_client_portal]` shortcode or the **Ndizi Client Portal** block in the block
   editor. Clients can review projects, verify tasks, download invoices, and submit
   new requests.
 * **Secure Passwordless Portal Auth**: Authorize client portal sessions using unique,
   secure client authentication keys, avoiding the need for clients to create standard
   WordPress user accounts.
 * **Collaborative Discussions**: Task and project comment boxes are filtered and
   embedded into the Client Portal, allowing team members and clients to exchange
   feedback and upload file attachments.
 * **Email Notifications**: Sends emails when a task is assigned or reassigned to
   a team member, and when a task’s status changes.
 * **Outbound Webhooks & Slack**: Dispatches JSON event payloads to a configurable
   webhook endpoint and formatted messages to a Slack incoming webhook on timer 
   events, time entry CRUD, CPT status transitions, and task/invoice metadata changes.
 * **Time Entry Approval Workflow**: Time entries carry `approved` and `approved_by`
   fields. Once approved, entries cannot be edited or deleted through normal write
   paths — only the approval status itself can be updated. Approval-only updates
   bypass lock-date enforcement.
 * **Google Calendar Sync**: When Google OAuth2 credentials are configured in Settings,
   tasks with due dates are synced to Google Calendar and time entries are pushed
   after each stop or manual log. An iCal subscription feed is available at `/wp-
   json/ndizi/v1/calendar/ical`.
 * **Stripe Online Payments**: Configure Stripe API keys in Settings to add a “Pay
   Online” button to unpaid invoices in the client portal. The plugin creates a 
   Stripe Checkout session via the REST API and auto-marks invoices paid via the
   Stripe webhook endpoint.
 * **Client Portal Time-Off Requests**: Clients and team members can submit time-
   off and absence requests directly from the portal sidebar. Requests are stored
   as `ndizi_time_off` posts with start/end dates, type, and approval status.
 * **Browser Extension**: A companion Chrome extension (`chrome-extension/`) connects
   to the site’s REST API to start/stop timers, browse projects and tasks, and open
   the standalone tracker — from any browser tab.
 * **REST API Integration**: Custom API routes under `/wp-json/ndizi/v1` let desktop
   widgets or mobile timekeepers start, stop, log, list, edit, and delete timer 
   entries remotely.
 * **WP-CLI Commands**: Manage timers from the terminal with `wp ndizi time start`,`
   wp ndizi time stop`, and `wp ndizi time status`. Accepts project/task names or
   IDs, user login or ID, description, and billable flag.
 * **Modular Architecture**: Each major feature group (Invoicing, Client Portal,
   Admin Bar Tracker, Email Notifications, Gantt Charts, Webhooks) can be individually
   toggled on or off from the Settings page. Inactive modules are not loaded, reducing
   overhead on sites that don’t need every feature.

### External services

This plugin can connect to third-party services, but **only after a site administrator
explicitly configures and enables the relevant integration**. Out of the box, with
no credentials entered and the optional features left at their defaults, the plugin
makes **no** requests to any external service. Each integration below is opt-in:
it stays dormant until you supply its API keys / credentials (or, for Google Fonts,
tick its checkbox) on the Ndizi PM  Settings screen.

#### Google Calendar API

Used by the optional “Google Calendar Sync” module to mirror task due dates and 
project milestones to your Google Calendar. It is only active after an administrator
enters Google OAuth credentials and connects an account on the Settings screen.

When a task with a due date is created, updated, or deleted, the plugin sends that
task’s title, description, and start/end date-times to the Google Calendar API (`
https://www.googleapis.com/calendar/v3/...`) authenticated with the connected account’s
access token. No data is sent until an account is connected, and nothing is sent
for sites that never enable the integration.

Google’s terms and privacy policy: https://policies.google.com/terms and https://
policies.google.com/privacy

#### Google OAuth 2.0

Used to authenticate the Google Calendar integration above. When an administrator
clicks “Connect to Google Calendar,” the plugin exchanges the authorization code,
and later refreshes the access token, against Google’s OAuth token endpoint (`https://
oauth2.googleapis.com/token`). The data sent is the OAuth client ID, client secret,
and authorization/refresh token that the administrator configured. This only happens
during the connect flow and subsequent token refreshes for a connected account.

Google’s terms and privacy policy: https://policies.google.com/terms and https://
policies.google.com/privacy

#### Stripe API

Used by the optional “Invoicing & Billing” module to let clients pay invoices online.
It is only active after an administrator enters Stripe API keys on the Settings 
screen.

When a client chooses to pay an invoice, the plugin creates a Stripe Checkout session
by sending the invoice amount, currency, description, invoice ID, and success/cancel
URLs to the Stripe API (`https://api.stripe.com/v1/checkout/sessions`), authenticated
with the configured Stripe secret key. The plugin also receives Stripe webhook callbacks
to mark invoices paid. No data is sent until Stripe keys are configured and a client
initiates a payment.

Stripe’s terms and privacy policy: https://stripe.com/legal/ssa and https://stripe.
com/privacy

#### Google Fonts

The client portal, the standalone time tracker, and printable invoices can use the
Inter and Outfit webfonts served by Google Fonts. This is **off by default**. When
an administrator enables “Load Google Fonts” under Ndizi PM  Settings  Typography,
the affected pages request stylesheets and font files from Google’s servers (`https://
fonts.googleapis.com` and `https://fonts.gstatic.com`); as with any web request,
this exposes the visitor’s IP address and user agent to Google. When the setting
is disabled (the default), the plugin uses a web-safe system font stack and makes
no requests to Google.

Google’s terms and privacy policy: https://policies.google.com/terms and https://
policies.google.com/privacy

## Screenshots

[⌊Reports Dashboard: Interactive, responsive summaries of billable time allocations
and user productivity, with date-range and project/user filters.⌉⌊Reports Dashboard:
Interactive, responsive summaries of billable time allocations and user productivity,
with date-range and project/user filters.⌉[

**Reports Dashboard**: Interactive, responsive summaries of billable time allocations
and user productivity, with date-range and project/user filters.

[⌊Gantt Timelines: Native project schedules mapping project milestones and task 
completion rates.⌉⌊Gantt Timelines: Native project schedules mapping project milestones
and task completion rates.⌉[

**Gantt Timelines**: Native project schedules mapping project milestones and task
completion rates.

[⌊Client Portal: Responsive frontend client portal featuring glassmorphic style 
controls.⌉⌊Client Portal: Responsive frontend client portal featuring glassmorphic
style controls.⌉[

**Client Portal**: Responsive frontend client portal featuring glassmorphic style
controls.

[⌊Invoice Meta Box: Aggregating un-invoiced project logs into line-item details 
with hierarchical billing rate resolution.⌉⌊Invoice Meta Box: Aggregating un-invoiced
project logs into line-item details with hierarchical billing rate resolution.⌉[

**Invoice Meta Box**: Aggregating un-invoiced project logs into line-item details
with hierarchical billing rate resolution.

## Blocks

This plugin provides 1 block.

 *   Ndizi Client Portal Embeds the Ndizi Client Portal for tracking projects, tasks,
   and invoices.

## Installation

 1. Upload the `ndizi-project-management` folder to the `/wp-content/plugins/` directory,
    or install it directly via the WordPress Admin Plugins dashboard.
 2. Activate the plugin. The database table `wp_ndizi_time_entries` and custom roles
    will be initialized automatically.
 3. Create a new WordPress Page for your client dashboard and add the **Ndizi Client
    Portal** block, or embed the `[ndizi_client_portal]` shortcode.
 4. Navigate to **Ndizi PM** -> **Clients** in your admin panel, register a new client,
    and generate a portal access key.

## FAQ

### Can I try the plugin before installing it?

Yes. Use the **Live Preview** button on this page, or [launch the demo directly in WordPress Playground](https://playground.wordpress.net/?blueprint-url=https://ps.w.org/ndizi-project-management/assets/blueprints/blueprint.json).
Either way you get a disposable, in-browser WordPress with Ndizi PM activated and
seeded with sample clients, projects, tasks, invoices, and time entries (including
a live running timer and a locked accounting period). It runs entirely in your browser
and nothing is saved.

### Where is the time tracking data stored?

High-frequency time entries (timer starts, stops, descriptions, and durations) are
logged in the dedicated `wp_ndizi_time_entries` table. Relational objects like Projects
and Tasks utilize standard Custom Post Types to maintain editing workflows, list
filters, and default REST support.

### Do clients need standard WordPress accounts to log in?

No. While standard WordPress accounts are fully supported, you can generate a private**
Client Auth Key** for any Client CPT. Navigating to the client portal with `?ndizi_token
=YOUR_KEY` authorizes their session, setting a secure cookie that keeps them logged
in.

### How does the file attachment system in discussions work?

Discussion boards on tasks and projects utilize WordPress’s native comments database
but filter comments to only show portal discussions. If files are uploaded through
the intake forms or discussion boxes, they are saved as secure media attachments
in the uploads directory and associated with the comment meta.

### How do managers construct invoices?

Inside any Invoice post, choose the parent Project. The dashboard will query the
time logging database for all un-invoiced billable hours on that project. The billing
rate for each time entry is resolved hierarchically: task-level override first, 
then the assigned user’s default rate, then the project’s default rate. Select the
hours to include and the editor will aggregate the line items, calculate the total,
and lock those time entries to the invoice.

### What is the lock date used for?

The lock date (configured on the Settings page) prevents any time entry dated on
or before that date from being created, edited, or deleted. Use it to protect finalized
billing periods once invoices have been sent. The lock is enforced across the REST
API, direct DB operations, and the admin UI.

### How does the hierarchical billing rate work?

When generating an invoice or report, Ndizi resolves the billing rate in this order:(
1) the task’s own hourly rate override, (2) the assigned user’s billing rate from
their profile, (3) the project’s default hourly rate. An explicit rate of 0.00 at
any level is honored rather than falling through to the next tier, making it possible
to mark individual tasks or projects as pro-bono.

### Can I export time data for accounting software?

Yes. The Reports dashboard has an “Export QuickBooks CSV” button that downloads 
a CSV formatted for direct import into QuickBooks (Customer, Item, Date, Hours, 
Rate, Description columns). The active date range, project, and user filters carry
through to the export. A standard CSV export is also available from the same dashboard.
Individual invoice line items can be exported as CSV or JSON from the invoice editor
screen.

### Can I use WP-CLI to manage timers?

Yes. Use `wp ndizi time start --project="My Project" --description="Working on feature
X"` to start a timer, `wp ndizi time stop` to stop it, and `wp ndizi time status`
to check what’s running. All commands accept `--user=<login|id>` to target a specific
team member. `--project` and `--task` accept either an exact post title or a post
ID.

### Does the plugin support third-party REST integrations?

Yes. Fully authenticated REST routes are exposed under `/wp-json/ndizi/v1/time` 
for starting, stopping, logging, listing, editing, and deleting timer entries. This
enables desktop timekeepers, browser extensions, or mobile apps to communicate with
the plugin. All write routes enforce the lock date.

### Can I receive notifications when timer events or task updates occur?

Yes. The Integrations module posts JSON webhook payloads to a configurable URL on
timer CRUD operations, CPT status transitions, and task/invoice metadata changes.
A separate Slack webhook URL field sends formatted messages to any Slack channel.
The Notifications module sends email to assigned team members when a task is assigned
or when its status changes.

### Can I turn off features I don’t need?

Yes. The Settings page (Ndizi PM  Settings) lists all feature modules. Uncheck any
module to disable it. Inactive modules are not loaded by the plugin, so their CPTs,
hooks, and admin pages simply don’t exist — useful for keeping things lean on sites
that only need time tracking without the full feature set.

### Where is the source code for the compiled JavaScript and CSS?

The uncompressed, human-readable source for every compiled asset in `build/` ships
alongside it in the `src/` directory of the plugin (and is mirrored in the public
Git repository at https://github.com/georgestephanis/plugins). The assets are built
with [@wordpress/scripts](https://www.npmjs.com/package/@wordpress/scripts): run`
npm install` followed by `npm run build:all` (which runs `npm run build:vendor` 
and `npm run build`) to regenerate the contents of `build/` from `src/`.

## Reviews

There are no reviews for this plugin.

## Contributors & Developers

“Ndizi Project Management” is open source software. The following people have contributed
to this plugin.

Contributors

 *   [ George Stephanis ](https://profiles.wordpress.org/georgestephanis/)

[Translate “Ndizi Project Management” into your language.](https://translate.wordpress.org/projects/wp-plugins/ndizi-project-management)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/ndizi-project-management/),
check out the [SVN repository](https://plugins.svn.wordpress.org/ndizi-project-management/),
or subscribe to the [development log](https://plugins.trac.wordpress.org/log/ndizi-project-management/)
by [RSS](https://plugins.trac.wordpress.org/log/ndizi-project-management/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 1.0.2

 * Google Fonts (Inter & Outfit) are now opt-in: a new Settings  Typography toggle,
   off by default, gates all requests to Google’s font servers. When disabled, the
   UI uses a web-safe system font stack.
 * Compiled assets now ship with their human-readable source: the `src/` directory
   is included in the package, and the readme documents how to rebuild `build/` 
   from it.
 * Inline scripts and styles are now routed through the WordPress enqueue system(`
   wp_enqueue_*`, `wp_localize_script()`, `wp_add_inline_script()`, `wp_add_inline_style()`,`
   wp_print_styles()`/`wp_print_scripts()`) instead of hardcoded `<link>`/`<script
   >` tags or echoed `<style>` blocks.
 * REST URLs are now built with `rest_url()` (and `add_query_arg()`) instead of 
   hardcoding the `/wp-json/` path, so the iCal feed and Stripe webhook URLs work
   across custom REST prefixes.
 * Documented all third-party services (Google Calendar, Google OAuth, Stripe, Google
   Fonts) in a new “External services” readme section.

#### 1.0.1

 * Fixed a `_load_textdomain_just_in_time` notice (WP 6.7+) caused by translations
   running before the `init` action; the module registry is now translation-free
   and labels load at display time.
 * Fixed the Playground demo not seeding mock data: the destructive-seed guard keyed
   on an unreliable Playground check, so it blocked seeding. It now gates on the
   environment type, and the demo blueprints declare a non-production environment.
 * WordPress.org Plugin Check pass: direct-file-access guards on block render and
   seed templates, prefixed/scoped file-scope variables, and documented database-
   query annotations.
 * Added a WordPress Playground live demo (Live Preview blueprint).
 * Now requires WordPress 6.9 or later (for the Abilities API integration).

#### 1.0.0

 * First stable release.
 * New **Time Entries** management screen (Ndizi PM  Time Entries) built on `@wordpress/
   dataviews`: sortable, filterable table of all time logs with merged Project/Task
   and Date columns.
 * Manager-facing approval workflow UI: multi-select bulk **Approve** / **Unapprove**
   actions on the Time Entries screen (manager-only). Approval-only updates are 
   permitted even inside locked billing periods.
 * Time-entry datetimes now render from UTC to site-local time in the table.
 * Shared DataViews vendor bundle (`build/vendor-dataviews.js`/`.css`) registered
   as the `ndizi-dataviews` script/style handles for reuse across admin screens.
 * Hardening and correctness fixes: time-entry approval restricted to managers with`
   approved_by` controlled server-side, dev seeder (`?ndizi_seed`) guarded against
   unauthorized use, REST error codes/statuses mapped correctly for time-log writes,
   and `per_page`/`page` clamped on time-log queries.

#### 1.0.0-alpha.2

 * Google Calendar integration: tasks and time entries synced via OAuth2; iCal subscription
   feed at `/wp-json/ndizi/v1/calendar/ical`.
 * Stripe online payment: “Pay Online” button in client portal, Stripe Checkout 
   session REST endpoint, and webhook auto-mark-paid handler.
 * Client portal time-off/absence request form (creates `ndizi_time_off` CPT posts).
 * Time entry approval workflow: `approved` / `approved_by` DB columns; approved
   entries block edits and deletion.
 * Chrome browser extension for timer control from any browser tab.
 * Standalone tracker: responsive CSS at ≤480 px, browser push notifications for
   idle timer, `?desc=` pre-fill parameter.
 * Auto DB schema upgrade on plugin init via `ndizi_db_version` version check.
 * `GET /calendar/ical`, `POST /invoices/<id>/pay`, `POST /stripe/webhook` REST 
   routes added.
 * Portal scripts now receive `rest_url` for client-side REST calls.
 * WordPress Abilities API: Ndizi capabilities exposed via `Ndizi_Abilities` for
   agentic/MCP workflows.
 * Settings page: Google OAuth connect button, Stripe API key fields.

#### 1.0.0-alpha

 * Initial release.
 * Decoupled SQL schema database initialization (`wp_ndizi_time_entries`).
 * Custom Post Types and taxonomy metadata setups.
 * Integrated admin bar active timer with customizable icons and idle warning banner.
 * Lock date / time entry locking enforced across REST API, DB layer, and admin 
   UI.
 * Hierarchical billing rates (task then user then project) on invoices and reports.
 * Gantt charts and dashboard report pages with date-range, project, and user filters.
 * Date-range filtered time reports with standard CSV and QuickBooks CSV export.
 * Invoice line-item CSV and JSON exports.
 * Shortcode- and block-driven frontend portal with passwordless token auth.
 * Email notifications for task assignment and status changes.
 * Outbound webhooks and Slack incoming webhook integration.
 * WP-CLI `wp ndizi time` command group (start, stop, status).
 * Modular architecture: feature modules toggleable from the Settings page.
 * REST API controller for external timer integration.
 * Standalone PWA dark glassmorphic tracker page.
 * Hardening: per-post-type verification on meta-box saves, MIME/size/count limits
   on portal uploads, CSV formula-injection escaping on exports, sanitize callbacks
   on time-entry REST routes, cryptographically secure client auth-key generator,
   non-negative rate validation.

## Meta

 *  Version **1.0.2**
 *  Last updated **15 hours ago**
 *  Active installations **10+**
 *  WordPress version ** 6.9 or higher **
 *  Tested up to **7.0**
 *  PHP version ** 7.4 or higher **
 * Tags
 * [clients](https://wordpress.org/plugins/tags/clients/)[invoices](https://wordpress.org/plugins/tags/invoices/)
   [project management](https://wordpress.org/plugins/tags/project-management/)[Tasks](https://wordpress.org/plugins/tags/tasks/)
   [Time Tracking](https://wordpress.org/plugins/tags/time-tracking/)
 *  [Advanced View](https://wordpress.org/plugins/ndizi-project-management/advanced/)

## Ratings

 3.5 out of 5 stars.

 *  [  2 5-star reviews     ](https://wordpress.org/support/plugin/ndizi-project-management/reviews/?filter=5)
 *  [  0 4-star reviews     ](https://wordpress.org/support/plugin/ndizi-project-management/reviews/?filter=4)
 *  [  0 3-star reviews     ](https://wordpress.org/support/plugin/ndizi-project-management/reviews/?filter=3)
 *  [  2 2-star reviews     ](https://wordpress.org/support/plugin/ndizi-project-management/reviews/?filter=2)
 *  [  0 1-star reviews     ](https://wordpress.org/support/plugin/ndizi-project-management/reviews/?filter=1)

[Your review](https://wordpress.org/support/plugin/ndizi-project-management/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/ndizi-project-management/reviews/)

## Contributors

 *   [ George Stephanis ](https://profiles.wordpress.org/georgestephanis/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/ndizi-project-management/)