mirror of
https://github.com/tdurieux/anonymous_github.git
synced 2026-09-12 13:48:58 +02:00
"Report an issue" in the navbar read like a way to report an anonymized
repository, and it opened a blank GitHub issue instead of the template
that asks reporters to confirm the issue is about the service. The user
menu offered "Default settings" and "Logout" with no hint of what lives
behind them, and the Claim page was unreachable from any menu.
The settings page never loaded quotas (the bars stayed in their striped
loading state), mixed serif checkbox labels with sans forms, used
Bootstrap alert colours, and described options in jargon ("Proxy mode",
"Github page", "Line of code").
- Navbar: "Report a bug" links to the issue template with a tooltip that
names the service; the user menu shows who is signed in and lists
Settings, Claim an anonymization, Report a bug, Source code, Sign out,
each with a one-line hint. Icon links get aria-labels.
- Settings: quotas load through a shared quotaService (also used by the
dashboard); sections match the side navigation, which now follows
scrolling via a small paperScrollspy directive; copy explains each
option; account card with Sign out; delete moved into a danger zone;
Save shows Saving/Saved and the error alert uses the paper palette.
- Conferences list and detail: sort and status buttons show their state,
hidden statuses appear as chips with a count line, Remove is a button
behind a divider, dates spell the month, expiry column matches the
dashboard, detail page gets an Edit button and plan/cost meta.
- New conference: validation errors only appear after a field is touched
or the form submitted; pricing copy matches how price is computed.
- Status page: progress label no longer overlaps the details below it;
"Report a bug" points at the template and says whom it is for.
- Claim: single rule, constrained width, explains when to use it.
- Anonymize: shorter placeholder, consistent Auto-update label.
- Mock server gains the endpoints these pages need and an ANON mode.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
269 lines
13 KiB
HTML
269 lines
13 KiB
HTML
<div class="container paper-page paper-settings">
|
|
<div class="paper-crumbs"><a href="/dashboard">My work</a> / <a href="/conferences">Conferences</a> / <span class="here">{{editionMode ? 'Edit' : 'New'}}</span></div>
|
|
<h1 class="paper-page-title">{{editionMode ? 'Edit' : 'Create a'}} <em>conference</em></h1>
|
|
<p class="paper-page-lede">
|
|
Give chairs access to every anonymization submitted to a venue, and lift
|
|
author quotas during the review window.
|
|
</p>
|
|
|
|
<div class="paper-settings-body">
|
|
<aside class="paper-settings-toc" paper-scrollspy>
|
|
<div class="paper-settings-toc-head">On this page</div>
|
|
<nav>
|
|
<a href="#conf-basics">Basics</a>
|
|
<a href="#conf-window">Review window</a>
|
|
<a href="#conf-rendering">Rendering defaults</a>
|
|
<a href="#conf-features">Features</a>
|
|
<a href="#conf-plan">Plan</a>
|
|
<a href="#conf-billing" ng-show="plan.pricePerRepo > 0">Billing</a>
|
|
</nav>
|
|
</aside>
|
|
|
|
<form class="form needs-validation paper-settings-main" name="conference" novalidate>
|
|
<section id="conf-basics" class="paper-settings-section">
|
|
<div class="paper-section-eyebrow">Basics</div>
|
|
|
|
<div class="form-group">
|
|
<label class="paper-field-label" for="name">Conference name</label>
|
|
<input
|
|
type="text"
|
|
class="form-control"
|
|
name="name"
|
|
id="name"
|
|
required
|
|
ng-class="{'is-invalid': conference.name.$invalid && (conference.name.$touched || conference.$submitted)}"
|
|
ng-model="options.name"
|
|
placeholder="e.g. International Conference on Software Engineering"
|
|
/>
|
|
<div class="invalid-feedback" ng-show="conference.name.$error.invalid">
|
|
The name of the conference is invalid.
|
|
</div>
|
|
<div class="invalid-feedback" ng-show="conference.name.$error.required">
|
|
The name of the conference is required.
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="paper-field-label" for="url">Website</label>
|
|
<input
|
|
type="url"
|
|
class="form-control"
|
|
name="url"
|
|
id="url"
|
|
ng-class="{'is-invalid': conference.url.$invalid && (conference.url.$touched || conference.$submitted)}"
|
|
ng-model="options.url"
|
|
placeholder="https://example.org"
|
|
/>
|
|
<div class="invalid-feedback" ng-show="conference.url.$error.invalid">
|
|
The url of the conference is invalid.
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="paper-field-label" for="conferenceID">Conference ID</label>
|
|
<input
|
|
type="text"
|
|
class="form-control"
|
|
name="conferenceID"
|
|
id="conferenceID"
|
|
required
|
|
pattern="[a-zA-Z0-9\-_]{3,10}"
|
|
ng-class="{'is-invalid': conference.conferenceID.$invalid && (conference.conferenceID.$touched || conference.$submitted)}"
|
|
ng-model="options.conferenceID"
|
|
placeholder="ICSE26"
|
|
/>
|
|
<small class="form-text text-muted">3–10 characters, letters, numbers, <code>-</code> and <code>_</code>. Authors reference this when they anonymize.</small>
|
|
<div class="invalid-feedback" ng-show="conference.conferenceID.$error.used">
|
|
The conference ID '{{options.conferenceID}}' is already used.
|
|
</div>
|
|
<div class="invalid-feedback" ng-show="conference.conferenceID.$error.required">
|
|
The conference ID is required.
|
|
</div>
|
|
<div class="invalid-feedback" ng-show="conference.conferenceID.$error.pattern">
|
|
The format of the conference ID is incorrect ([a-zA-Z0-9-_]{3,10}).
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="conf-window" class="paper-settings-section">
|
|
<div class="paper-section-eyebrow">Review window</div>
|
|
|
|
<div class="form-grid-2">
|
|
<div class="form-group">
|
|
<label class="paper-field-label" for="startDate">Start date</label>
|
|
<input
|
|
type="date"
|
|
class="form-control"
|
|
name="startDate"
|
|
id="startDate"
|
|
required
|
|
ng-class="{'is-invalid': conference.startDate.$invalid && (conference.startDate.$touched || conference.$submitted)}"
|
|
ng-model="options.startDate"
|
|
/>
|
|
<small class="form-text text-muted">Beginning of the review process.</small>
|
|
<div class="invalid-feedback" ng-show="conference.startDate.$error.required">
|
|
Start date is required.
|
|
</div>
|
|
<div class="invalid-feedback" ng-show="conference.startDate.$error.invalid">
|
|
Start date must be before end date.
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="paper-field-label" for="endDate">End date</label>
|
|
<input
|
|
type="date"
|
|
class="form-control"
|
|
name="endDate"
|
|
id="endDate"
|
|
required
|
|
ng-class="{'is-invalid': conference.endDate.$invalid && (conference.endDate.$touched || conference.$submitted)}"
|
|
ng-model="options.endDate"
|
|
/>
|
|
<small class="form-text text-muted">All repositories expire on this date.</small>
|
|
<div class="invalid-feedback" ng-show="conference.endDate.$error.required">
|
|
End date is required.
|
|
</div>
|
|
<div class="invalid-feedback" ng-show="conference.endDate.$error.invalid">
|
|
End date is invalid.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="conf-rendering" class="paper-settings-section">
|
|
<div class="paper-section-eyebrow">Rendering defaults</div>
|
|
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="link" name="link" ng-model="options.options.link" />
|
|
<label class="form-check-label" for="link">Keep links</label>
|
|
<small class="form-text text-muted">Keep or remove all links from text files.</small>
|
|
</div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="image" name="image" ng-model="options.options.image" />
|
|
<label class="form-check-label" for="image">Display images</label>
|
|
<small class="form-text text-muted">Images are not anonymized.</small>
|
|
</div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="pdf" name="pdf" ng-model="options.options.pdf" />
|
|
<label class="form-check-label" for="pdf">Display PDFs</label>
|
|
<small class="form-text text-muted">PDFs are not anonymized.</small>
|
|
</div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="notebook" name="notebook" ng-model="options.options.notebook" />
|
|
<label class="form-check-label" for="notebook">Display Notebooks</label>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="conf-features" class="paper-settings-section">
|
|
<div class="paper-section-eyebrow">Features</div>
|
|
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="update" name="update" ng-model="options.options.update" />
|
|
<label class="form-check-label" for="update">Auto-update from GitHub</label>
|
|
<small class="form-text text-muted">Pull the latest commit automatically (hourly maximum).</small>
|
|
</div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="page" name="page" ng-model="options.options.page" />
|
|
<label class="form-check-label" for="page">GitHub Pages</label>
|
|
<small class="form-text text-muted">Enable anonymized GitHub pages.</small>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="conf-plan" class="paper-settings-section">
|
|
<div class="paper-section-eyebrow">Plan</div>
|
|
<p class="paper-section-copy">Billed per repository per month, prorated by the day for as long as a repository stays in the conference.</p>
|
|
|
|
<div class="paper-plan-grid">
|
|
<label
|
|
class="paper-plan-card"
|
|
ng-class="{'selected': options.plan.planID == plan.id}"
|
|
ng-repeat="plan in plans"
|
|
>
|
|
<input
|
|
type="radio"
|
|
name="planPicker"
|
|
ng-value="plan.id"
|
|
ng-model="options.plan.planID"
|
|
/>
|
|
<div class="paper-plan-head" ng-bind="plan.name"></div>
|
|
<div class="paper-plan-price">
|
|
{{plan.pricePerRepo | number}}€
|
|
<span class="paper-plan-per">/ repo / month</span>
|
|
</div>
|
|
<div class="paper-plan-desc" ng-bind-html="plan.description"></div>
|
|
</label>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="conf-billing" class="paper-settings-section" ng-if="plan.pricePerRepo > 0">
|
|
<div class="paper-section-eyebrow">Billing</div>
|
|
|
|
<div class="form-group">
|
|
<label class="paper-field-label" for="billing_name">Name</label>
|
|
<input type="text" class="form-control" name="billing_name" id="billing_name" required
|
|
ng-class="{'is-invalid': conference.billing_name.$invalid && (conference.billing_name.$touched || conference.$submitted)}"
|
|
ng-model="options.billing.name" placeholder="First & last name" />
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="paper-field-label" for="email">Email</label>
|
|
<input type="email" class="form-control" name="email" id="email" required
|
|
ng-class="{'is-invalid': conference.email.$invalid && (conference.email.$touched || conference.$submitted)}"
|
|
ng-model="options.billing.email" placeholder="you@example.org" />
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="paper-field-label" for="inputAddress">Address</label>
|
|
<input type="text" class="form-control" name="inputAddress" id="inputAddress" required
|
|
placeholder="1234 Main St"
|
|
ng-model="options.billing.address"
|
|
ng-class="{'is-invalid': conference.inputAddress.$invalid && (conference.inputAddress.$touched || conference.$submitted)}" />
|
|
</div>
|
|
<div class="form-group">
|
|
<input type="text" class="form-control" name="inputAddress2" id="inputAddress2"
|
|
ng-model="options.billing.address2"
|
|
ng-class="{'is-invalid': conference.inputAddress2.$invalid && (conference.inputAddress2.$touched || conference.$submitted)}"
|
|
placeholder="Apartment, studio, or floor" />
|
|
</div>
|
|
|
|
<div class="form-grid-3">
|
|
<div class="form-group">
|
|
<label class="paper-field-label" for="city">City</label>
|
|
<input type="text" class="form-control" name="city" id="city"
|
|
ng-model="options.billing.city" required
|
|
ng-class="{'is-invalid': conference.city.$invalid && (conference.city.$touched || conference.$submitted)}" placeholder="City" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="paper-field-label" for="country">Country</label>
|
|
<input type="text" class="form-control" name="country" id="country"
|
|
ng-model="options.billing.country" required
|
|
ng-class="{'is-invalid': conference.country.$invalid && (conference.country.$touched || conference.$submitted)}" placeholder="Country" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="paper-field-label" for="zip">Zip</label>
|
|
<input type="text" class="form-control" name="zip" id="zip"
|
|
ng-model="options.billing.zip" required
|
|
ng-class="{'is-invalid': conference.zip.$invalid && (conference.zip.$touched || conference.$submitted)}" placeholder="Zip" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="paper-field-label" for="vat">VAT number</label>
|
|
<input type="text" class="form-control" name="vat" id="vat"
|
|
ng-class="{'is-invalid': conference.vat.$invalid && (conference.vat.$touched || conference.$submitted)}"
|
|
ng-model="options.billing.vat" placeholder="VAT Number" />
|
|
</div>
|
|
</section>
|
|
|
|
<div class="paper-settings-footer">
|
|
<div class="alert alert-danger" role="alert" ng-if="error" ng-bind="error"></div>
|
|
<div class="alert alert-success" role="alert" ng-if="message" ng-bind="message"></div>
|
|
<button id="send" type="submit" class="btn btn-ink" ng-click="submit($event)">
|
|
{{editionMode ? "Update" : "Create"}} conference
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|