Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
116 changes: 109 additions & 7 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -343,11 +343,25 @@ resolver = "2"</code></pre>
<span>Project or contract path</span>
<span className="badge badge-required">Required</span>
</div>
<input
value={path}
onChange={(event) => setPath(event.target.value)}
aria-required="true"
/>
<div className="field-with-clear">
<input
className={fieldClasses}
value={path}
onChange={(event) => setPath(event.target.value)}
aria-label="Project or contract path"
aria-required="true"
/>
{path && (
<button
type="button"
className="clear-field-button"
onClick={() => setPath("")}
aria-label="Clear"
>
Clear
</button>
)}
</div>
</label>
{command === "coverage" && <>
<label>
Expand Down Expand Up @@ -375,14 +389,50 @@ resolver = "2"</code></pre>
<span>Function</span>
<span className="badge badge-required">Required</span>
</div>
<input value={fn} onChange={(event) => setFn(event.target.value)} aria-required="true" />
<div className="field-with-clear">
<input
className={fieldClasses}
value={fn}
onChange={(event) => setFn(event.target.value)}
aria-label="Function"
aria-required="true"
/>
{fn && (
<button
type="button"
className="clear-field-button"
onClick={() => setFn("")}
aria-label="Clear"
>
Clear
</button>
)}
</div>
</label>
<label>
<div className="field-header">
<span>Ramp parameter</span>
<span className="badge badge-required">Required</span>
</div>
<input value={ramp} onChange={(event) => setRamp(event.target.value)} aria-required="true" />
<div className="field-with-clear">
<input
className={fieldClasses}
value={ramp}
onChange={(event) => setRamp(event.target.value)}
aria-label="Ramp parameter"
aria-required="true"
/>
{ramp && (
<button
type="button"
className="clear-field-button"
onClick={() => setRamp("")}
aria-label="Clear"
>
Clear
</button>
)}
</div>
</label>
</div>}
{command === "audit" && <label className="check">
Expand Down Expand Up @@ -602,6 +652,58 @@ resolver = "2"</code></pre>
)}
</section>

<section className="guides" aria-label="Workflow guides">
<article className="guide-card">
<div className="guide-header">
<h3>Coverage report guide</h3>
<button
type="button"
className="guide-toggle"
aria-expanded={coverageGuideOpen}
aria-controls="coverage-guide-panel"
onClick={() => setCoverageGuideOpen((open) => !open)}
>
{coverageGuideOpen ? "Hide guide" : "Show guide"}
</button>
</div>
{coverageGuideOpen && (
<div id="coverage-guide-panel" className="guide-panel">
<ol>
<li>Start with the local project path so the tool can read the crate and tests in context.</li>
<li>Choose HTML output when you want a visual report and open it immediately after generation.</li>
<li>Read branch and line coverage together: low execution density usually explains weak confidence more than raw percentages.</li>
<li>Use the report to prioritize untested edge cases before shipping a contract update.</li>
</ol>
</div>
)}
</article>

<article className="guide-card">
<div className="guide-header">
<h3>Audit workflow tutorial</h3>
<button
type="button"
className="guide-toggle"
aria-expanded={auditGuideOpen}
aria-controls="audit-guide-panel"
onClick={() => setAuditGuideOpen((open) => !open)}
>
{auditGuideOpen ? "Hide tutorial" : "Show tutorial"}
</button>
</div>
{auditGuideOpen && (
<div id="audit-guide-panel" className="guide-panel">
<ol>
<li>Point the audit at the contract source directory or workspace root most relevant to the change.</li>
<li>Review auth and storage access warnings first; they often explain failure modes and privilege issues.</li>
<li>Use the strict mode toggle when you want warning-level findings to block release readiness.</li>
<li>Pair each finding with a focused regression test before finalizing the deployment checklist.</li>
</ol>
</div>
)}
</article>
</section>

<footer><span>Built for the Stellar developer ecosystem.</span><span>Apache-2.0</span></footer>
</main>
);
Expand Down
20 changes: 20 additions & 0 deletions src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -309,11 +309,31 @@ label { display: grid; gap: 9px; margin-bottom: var(--space-2xl); color: var(--c
}

.row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-xl); }
.field-with-clear {
display: flex;
align-items: center;
gap: 10px;
}
.field-input { width: 100%; }
input, select { width: 100%; padding: var(--space-md) 13px; color: var(--color-text-primary); background: var(--color-input-bg); border: 1px solid var(--color-border-input); border-radius: var(--radius-sm); outline: none; }
input:focus, select:focus { border-color: var(--color-accent); }
.clear-field-button {
border: 1px solid var(--color-border-strong);
background: transparent;
color: var(--color-text-secondary);
padding: 8px 10px;
border-radius: var(--radius-sm);
cursor: pointer;
white-space: nowrap;
}
.clear-field-button:hover, .clear-field-button:focus-visible {
color: var(--color-accent);
border-color: var(--color-accent);
}
.check { display: flex; align-items: center; justify-content: space-between; }
.check-content { display: flex; align-items: center; gap: var(--space-sm); }
.check input { width: auto; accent-color: var(--color-accent); }
.output-wrap { display: grid; gap: 10px; }
.output { display: flex; align-items: center; gap: 15px; padding: var(--space-lg); background: var(--color-surface-output); border-radius: var(--radius-md); }
.output code { flex: 1; color: var(--color-accent); font: .75rem/1.6 var(--font-mono); overflow-wrap: anywhere; }
.output button { color: var(--color-canvas); background: var(--color-accent); border: 0; border-radius: var(--radius-xs); padding: var(--space-sm) var(--space-md); cursor: pointer; font-weight: 600; }
Expand Down