PageSourceSearch

https://onplana.com/assets/ProjectTimeTracking-CtROspKT.js

js onplana.com collected 2026-09-24 13:40:34 UTC 16,218 bytes, 1 lines download raw bytes

1import{u as v,j as e,S as k,H as N,a as u,r as g,P as S}from"./index-D4J_1siJ.js";import{L as i}from"./react-Ckdnth5K.js";import{P as l,F as T,m as A}from"./plans-mAcoIctm.js";import{a0 as E,a as y,y as r}from"./icons-zJT0-GYi.js";const n="/features/project-time-tracking",c="https://onplana.com";function w(t){let a=null;for(const p of t){const x=T.flatMap(s=>s.rows).find(s=>s.label===p),j=x?A(x.values):null,h=l.find(s=>s.code===j);if(!h)throw new Error(`${n}: no pricing-matrix row "${p}" is sold on a plan`);(!a||l.indexOf(h)>l.indexOf(a))&&(a=h)}if(!a)throw new Error(`${n}: planSoldFrom needs at least one row`);return a}const R="Timesheets & approval workflow",C="Resource capacity planning",O="Earned value management",P="Rate cards (3 scopes)",o=w([R,C,O]),m=w([P]),f=o.freeGuestSeats,d=l.filter(t=>!t.contactSales),F={"@type":"AggregateOffer",priceCurrency:"USD",lowPrice:String(Math.min(...d.map(t=>t.monthlyPerSeat))),highPrice:String(Math.max(...d.map(t=>t.monthlyPerSeat))),offerCount:String(d.length),url:`${c}/pricing`},L=["Hours logged against the task rather than a separate project list","Configurable approval chain with named approvers","Copy last week, or prefill the week from the plan","Separate cost and billable rates, per user, role or organisation","Rates scoped per client and per project","Billable and total-hours utilisation views","Approved hours priced into earned value on the project","Guests can log time without a full seat"],I=[{title:"Log the hours where the work already is",body:"Hours go against the task, not against a second list of projects that drifts out of step with the first. Nobody wants to do this on a Friday, so the week can be copied from last week or prefilled from the plan, as drafts you correct rather than a blank grid you fill.",src:"/product/timesheet-tracking.webp",alt:"Logging hours against a task in the Onplana timesheet"},{title:"Approve the week, through people you named",body:"The approval chain is a list of approvers an owner or admin sets, not an inbox rule somebody has to remember. A submitted week goes to them, a rejection comes back with the reason attached, and the reviewer is stamped on the entry so the trail survives the conversation.",src:"/product/timesheet-approvals.webp",alt:"The timesheet approvals inbox, with a week awaiting review"},{title:"See what the time was worth, not just how much there was",body:"Approved hours price at the cost rate and the billable rate, which are separate numbers, and land on the project as earned value alongside the budget. The same hours feed the capacity view the plan is built on, so next week is planned against what happened rather than what was assumed.",src:"/product/project-finance-evm.webp",alt:"The project finance tab showing earned value against budget"}],b=[{q:"Is this a replacement for Harvest, Toggl or Clockify?",a:"For time that belongs to a project plan, yes, and the difference is where the hours go rather than how they are entered: they land on the task, so they feed the capacity view and the project's earned value instead of arriving as a monthly CSV somebody reconciles by hand. For workforce time and attendance it is not a replacement, and the next answer is the honest version of why."},{q:"Is there a start and stop timer, or a clock-in?",a:"No. There is no running timer, no clock-in terminal, no shift scheduling and no payroll. This is project time tracking: you record hours against the work they belong to, by the day. If what you need is a punch clock for hourly staff, this is the wrong tool and you should not buy it for that."},{q:"Can a part-timer log hours without paying for a full seat?",a:`Yes. A guest can log time on the projects they are on, and ${f===0?"guest seats are billed as seats on this plan":`the ${o.name} plan includes ${f} free guest seats`}. Beyond the included allowance a guest costs a seat like anyone else, so this is a real allowance rather than an unlimited one. Guests are also left out of the compliance roster on purpose: their week is reviewed when they log it, and they are never chased for a week they did not.`},{q:"Can I bill at a different rate than the hour costs me?",a:"Yes, and they are separate stored numbers rather than one rate with a multiplier applied at report time. Set a billable rate outright, or set a markup percentage on the cost rate, or set neither and the billable rate equals the cost rate with no margin. Rates resolve most specific first: this project, then this client, then the person, then their role, then the organisation default."},{q:"Does it sync to Xero or QuickBooks?",a:"Not today. That connector is not available to customers, so anyone who needs approved time to land in their ledger automatically should treat this as missing rather than pending. What you can do n
1ow is export: the cross-project report builder is on every plan with no upgrade, so approved hours come out as a file you take wherever they need to go."},{q:"Which plan is this on?",a:`${o.name}, with no seat minimum, and that covers timesheets, the approval chain, capacity and earned value. Rate cards are on the ${m.name} plan, which is deliberate: you can set your cost and billable rates and watch them resolve before you pay us for anything that uses them.`}];function _(){return v(n),e.jsxs(e.Fragment,{children:[e.jsx(k,{title:"Project Time Tracking Software: Hours That Land on the Plan",description:"Log hours against the task, approve the week through people you named, and price it at cost and billable rates. Rate cards free on every plan. No timer, no payroll.",path:n}),e.jsxs(N,{children:[e.jsx("script",{type:"application/ld+json",children:JSON.stringify({"@context":"https://schema.org","@type":"BreadcrumbList",itemListElement:[{"@type":"ListItem",position:1,name:"Home",item:`${c}/`},{"@type":"ListItem",position:2,name:"Features",item:`${c}/features`},{"@type":"ListItem",position:3,name:"Project Time Tracking",item:`${c}${n}`}]})}),e.jsx("script",{type:"application/ld+json",children:JSON.stringify({"@context":"https://schema.org","@type":"SoftwareApplication",name:"Onplana",applicationCategory:"BusinessApplication",applicationSubCategory:"ProjectManagementSoftware",operatingSystem:"Web",description:"Project time tracking attached to the plan: hours logged against the task, a configurable approval chain, separate cost and billable rates scoped per client and project, and approved time priced into the project's earned value.",featureList:L,offers:F})}),e.jsx("script",{type:"application/ld+json",children:JSON.stringify({"@context":"https://schema.org","@type":"FAQPage",mainEntity:b.map(t=>({"@type":"Question",name:t.q,acceptedAnswer:{"@type":"Answer",text:t.a}}))})})]}),e.jsx("section",{className:"section bg-gradient-to-b from-slate-50 to-white pt-16 sm:pt-20","data-sv":"hero",children:e.jsxs("div",{className:"container-lg text-center",children:[e.jsxs("div",{className:"badge bg-primary-50 text-primary-700 mb-6 inline-flex gap-2",children:[e.jsx(E,{className:"w-3.5 h-3.5"}),"Attached to the plan, not beside it"]}),e.jsx("h1",{className:"text-4xl sm:text-5xl font-extrabold text-gray-900 mb-5 leading-tight max-w-4xl mx-auto",children:"Track time against the plan, not in a separate app"}),e.jsx("p",{className:"text-lg sm:text-xl text-gray-500 max-w-3xl mx-auto mb-10",children:"Onplana logs hours against the task they belong to, runs the week through an approval chain you name, and prices it at both the cost rate and the billable rate, so what a month was worth is a number you read rather than one you reconstruct."}),e.jsx("div",{className:"flex justify-center",children:e.jsxs("a",{href:g(),className:"btn-primary inline-flex items-center gap-2",onClick:()=>u.ctaClick("Start free","features-project-time-tracking-hero"),children:["Start free ",e.jsx(y,{className:"w-4 h-4"})]})})]})}),e.jsx("section",{className:"section","data-sv":"before-after",children:e.jsxs("div",{className:"container-lg",children:[e.jsx("h2",{className:"text-3xl font-bold text-gray-900 mb-8 text-center",children:"What changes at the end of the month"}),e.jsxs("div",{className:"grid md:grid-cols-2 gap-6 max-w-4xl mx-auto",children:[e.jsxs("div",{className:"rounded-2xl border border-gray-200 bg-gray-50 p-6",children:[e.jsx("p",{className:"text-xs font-semibold tracking-wide uppercase text-gray-500 mb-4",children:"A tracker beside the plan"}),e.jsxs("ul",{className:"space-y-3 text-gray-700 text-sm",children:[e.jsx("li",{children:"Export last month's CSV out of the time tracker."}),e.jsx("li",{children:"Match each line to a project by hand, because the two project lists drifted."}),e.jsx("li",{children:"Open a second spreadsheet to find whose rate changed in April."}),e.jsx("li",{children:"Type the total into the invoice, then again into the capacity sheet."}),e.jsx("li",{children:"Discover in month three that one client was billed at last year's rate."})]})]}),e.jsxs("div",{className:"rounded-2xl border border-primary-200 bg-primary-50/40 p-6",children:[e.jsx("p",{className:"text-xs font-semibold tracking-wide uppercase text-primary-700 mb-4",children:"Hours on the plan itself"}),e.jsxs("ul",{className:"space-y-3 text-gray-700 text-sm",children:[e.jsxs("li",{className:"flex gap-2",children:[e.jsx(r,{className:"w-4 h-4 text-primary-600 shrink-0 mt-0.5"}),"Hours sit on the task, so there is nothing to match afterwards."]}),e.jsxs("li",{className:"flex gap-2",children:[e.jsx(r,{className:"w-4 h-4 text-primary-600 shrink-0 mt-0.5"}),"The approval chain is people you named, not a rule somebody remembers."]}),e.jsxs("li",{className:"flex gap-2",children:[e.jsx(r,{className:"w-4 h-4 text-primary-600 shrink-0 mt-0.5"}),"Cost and billable are separate rates, resolved per client and per project."]}),e.jsxs("li",{className:"flex gap-2",children:[e.jsx(r,{className:"w-4 h-4 text-primary-600 shrink-0 mt-0.5"}),"Approved time lands as earned value against the budget."]}),e.jsxs("li",{className:"flex gap-2",children:[e.jsx(r,{className:"w-4 h-4 text-primary-600 shrink-0 mt-0.5"}),"The same hours feed the capacity view next week is planned from."]})]})]})]})]})}),e.jsx("section",{className:"section bg-gray-50","data-sv":"how-it-works",children:e.jsxs("div",{className:"container-lg",children:[e.jsx("h2",{className:"text-3xl font-bold text-gray-900 mb-10 text-center",children:"How it works"}),e.jsx("div",{className:"space-y-14 max-w-4xl mx-auto",children:I.map((t,a)=>e.jsxs("div",{className:"grid md:grid-cols-2 gap-8 items-center",children:[e.jsxs("div",{className:a%2===1?"md:order-2":void 0,children:[e.jsxs("p",{className:"text-xs font-semibold tracking-wide uppercase text-primary-700 mb-2",children:["Step ",a+1]}),e.jsx("h3",{className:"text-xl font-bold text-gray-900 mb-3",children:t.title}),e.jsx("p",{className:"text-gray-600",children:t.body})]}),e.jsx(S,{src:t.src,alt:t.alt,className:a%2===1?"md:order-1":void 0})]},t.title))})]})}),e.jsx("section",{className:"section","data-sv":"proof",children:e.jsxs("div",{className:"container-lg max-w-3xl text-center",children:[e.jsx("h2",{className:"text-3xl font-bold text-gray-900 mb-4",children:"Check the arithmetic before you pay for it"}),e.jsxs("p",{className:"text-gray-600 mb-6",children:["The part of this that is easy to get wrong is the money, so the money part is on the free plan. Rate cards are on ",e.jsx("strong",{children:m.name}),": set your cost rates and your billable rates, add a client or a project that prices differently, and watch the resolver pick between them. If the maths does not match how you actually bill, you will know that in an afternoon and it will have cost you nothing."]}),e.jsxs("p",{className:"text-sm text-gray-500",children:["We are deliberately not quoting an industry figure about hours lost to timesheets. The only number that decides this is your own realisation rate against your own rate card, and 
1you can have that one for free. When you are ready for the hours themselves,"," ",e.jsxs(i,{to:"/pricing",className:"text-primary-700 hover:underline",children:["see what ",o.name," costs"]}),"."]})]})}),e.jsx("section",{className:"section bg-gray-50","data-sv":"cost-and-limit",children:e.jsxs("div",{className:"container-lg max-w-3xl",children:[e.jsx("h2",{className:"text-3xl font-bold text-gray-900 mb-6 text-center",children:"What it costs, and what it does not do"}),e.jsxs("div",{className:"rounded-2xl border border-gray-200 bg-white p-6 mb-5",children:[e.jsxs("p",{className:"text-gray-700",children:["Timesheets, the approval chain, capacity and earned value are on the"," ",e.jsx("strong",{children:o.name})," plan with no seat minimum, and rate cards are on"," ",m.name,". It replaces the standalone tracker whose only real job was feeding a spreadsheet somebody reconciles against the plan by hand."]}),e.jsx("p",{className:"text-sm text-gray-500 mt-3",children:e.jsx(i,{to:"/features/free-plan",className:"text-primary-700 hover:underline",children:"What the Free plan includes, and where it stops"})})]}),e.jsxs("div",{className:"rounded-2xl border border-amber-200 bg-amber-50 p-6",children:[e.jsx("p",{className:"text-sm font-semibold text-amber-900 mb-2",children:"The honest limits"}),e.jsxs("ul",{className:"space-y-3 text-sm text-amber-900",children:[e.jsxs("li",{children:[e.jsx("strong",{className:"font-semibold",children:"This is not workforce time and attendance."})," ","There is no running timer, no clock-in, no shift scheduling and no payroll. Hours are recorded against the work they belong to, by the day. If you are tracking hourly staff on site rather than effort against a plan, buy something else."]}),e.jsxs("li",{children:[e.jsx("strong",{className:"font-semibold",children:"There is no accounting sync."})," ","Approved time does not flow into Xero or QuickBooks on its own, and that is a gap rather than a roadmap promise. The cross-project report builder exports on every plan, so getting the hours out is a file you run, not an integration you wait for."]}),e.jsxs("li",{children:[e.jsx("strong",{className:"font-semibold",children:"Enforcement is an Enterprise thing."})," ","Reminders, the compliance view and the cost-at-risk number come with the plan above. Locking someone out of new work until last week is submitted, escalation chains and the auditor-ready evidence export are Enterprise, so if hard enforcement is the reason you are buying, price that tier rather than this one."]})]})]})]})}),e.jsx("section",{className:"section","data-sv":"faq",children:e.jsxs("div",{className:"container-lg max-w-3xl",children:[e.jsx("h2",{className:"text-3xl font-bold text-gray-900 mb-8 text-center",children:"Questions people ask before they switch"}),e.jsx("div",{className:"space-y-4",children:b.map(t=>e.jsxs("details",{className:"rounded-xl border border-gray-200 bg-white p-5",children:[e.jsx("summary",{className:"cursor-pointer font-semibold text-gray-900",children:t.q}),e.jsx("p",{className:"mt-3 text-gray-600 text-sm",children:t.a})]},t.q))}),e.jsxs("p",{className:"mt-8 text-sm text-gray-500 text-center",children:["If the question is who is free rather than what the week cost,"," ",e.jsx(i,{to:"/features/construction-resource-scheduling",className:"text-primary-700 hover:underline",children:"crew capacity across every job"})," ","covers the planning side, and"," ",e.jsx(i,{to:"/services/psa-for-small-consultancies",className:"text-primary-700 hover:underline",children:"PSA for small consultancies"})," ","covers the whole billable cycle from pipeline to invoice."]})]})}),e.jsx("section",{className:"section bg-gray-900","data-sv":"cta",children:e.jsxs("div",{className:"container-lg max-w-2xl text-center",children:[e.jsx("h2",{className:"text-3xl font-bold text-white mb-4",children:"Put your rates in and see the maths"}),e.jsx("p",{className:"text-gray-300 mb-8",children:"Rate cards are free, so you can check how your hours would price before you pay for a single timesheet. Nothing to install, and whatever you track time in today keeps working."}),e.jsxs("a",{href:g(),className:"btn-primary inline-flex items-center gap-2",onClick:()=>u.ctaClick("Start free","features-project-time-tracking-final"),children:["Start free ",e.jsx(y,{className:"w-4 h-4"})]})]})})]})}export{_ as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.