Skip to content

Commit

Permalink
feat: enhance onboarding experience and repository management in GitH…
Browse files Browse the repository at this point in the history
…ubSettings and ProjectsList components

- Introduced an onboarding flag in GitHubSettings to conditionally render repository input fields and messages.
- Updated the default values for repoName and branch in GitHubSettings for improved usability.
- Enhanced the ProjectsList component to provide clearer guidance when no projects are found, including prompts for creating or loading projects.
- Improved user feedback with contextual messages regarding repository existence and creation during onboarding.

These changes significantly enhance the user experience by streamlining the onboarding process and providing clearer instructions for managing GitHub repositories.
  • Loading branch information
mamertofabian committed Dec 29, 2024
1 parent 9cdd28d commit 6d82e30
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 102 deletions.
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "Bolt to GitHub",
"version": "1.1.4",
"version": "1.1.5",
"description": "Automatically process your Bolt project zip files and upload them to your GitHub repository.",
"icons": {
"16": "assets/icons/icon16.png",
Expand Down
195 changes: 99 additions & 96 deletions src/lib/components/GitHubSettings.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@
import { onMount } from 'svelte';
import { GitHubService } from "../../services/GitHubService";
export let isOnboarding: boolean = false;
export let githubToken: string;
export let repoOwner: string;
export let repoName: string;
export let branch: string;
export let repoName: string = '';
export let branch: string = 'main';
export let status: string;
export let isSettingsValid: boolean;
export let onSave: () => void;
Expand Down Expand Up @@ -199,7 +200,7 @@
}
}
$: if (projectId && projectSettings[projectId]) {
$: if (!isOnboarding && projectId && projectSettings[projectId]) {
repoName = projectSettings[projectId].repoName;
branch = projectSettings[projectId].branch;
}
Expand Down Expand Up @@ -331,117 +332,119 @@
/>
</div>

<div class="space-y-2">
<Label for="repoName" class="text-slate-200">
Repository Name
<span class="text-sm text-slate-400 ml-2">
{#if projectId}
(Project-specific repository)
{:else}
(Default repository)
{/if}
</span>
</Label>
<div class="relative">
<div class="relative">
<Input
type="text"
id="repoName"
bind:value={repoName}
on:input={handleRepoInput}
on:focus={handleRepoFocus}
on:blur={handleRepoBlur}
on:keydown={handleRepoKeydown}
placeholder="Search or enter repository name"
class="bg-slate-800 border-slate-700 text-slate-200 placeholder:text-slate-500 pr-10"
autocomplete="off"
/>
<div class="absolute right-3 top-1/2 -translate-y-1/2">
{#if isLoadingRepos}
<Loader2 class="h-4 w-4 text-slate-400 animate-spin" />
{#if !isOnboarding}
<div class="space-y-2">
<Label for="repoName" class="text-slate-200">
Repository Name
<span class="text-sm text-slate-400 ml-2">
{#if projectId}
(Project-specific repository)
{:else}
<Search class="h-4 w-4 text-slate-400" />
(Default repository)
{/if}
</span>
</Label>
<div class="relative">
<div class="relative">
<Input
type="text"
id="repoName"
bind:value={repoName}
on:input={handleRepoInput}
on:focus={handleRepoFocus}
on:blur={handleRepoBlur}
on:keydown={handleRepoKeydown}
placeholder="Search or enter repository name"
class="bg-slate-800 border-slate-700 text-slate-200 placeholder:text-slate-500 pr-10"
autocomplete="off"
/>
<div class="absolute right-3 top-1/2 -translate-y-1/2">
{#if isLoadingRepos}
<Loader2 class="h-4 w-4 text-slate-400 animate-spin" />
{:else}
<Search class="h-4 w-4 text-slate-400" />
{/if}
</div>
</div>
</div>
{#if showRepoDropdown && (filteredRepos.length > 0 || !repoExists)}
<div class="absolute z-50 w-full mt-1 bg-slate-800 border border-slate-700 rounded-md shadow-lg">
<ul class="py-1 max-h-60 overflow-auto">
{#each filteredRepos as repo, i}
<li>
<button
class="w-full px-3 py-2 text-left hover:bg-slate-700 text-slate-200 {selectedIndex === i ? 'bg-slate-700' : ''}"
on:click={() => selectRepo(repo)}
>
<div class="flex items-center justify-between">
<span class="font-medium">{repo.name}</span>
{#if repo.private}
<span class="text-xs text-slate-400">Private</span>
{#if showRepoDropdown && (filteredRepos.length > 0 || !repoExists)}
<div class="absolute z-50 w-full mt-1 bg-slate-800 border border-slate-700 rounded-md shadow-lg">
<ul class="py-1 max-h-60 overflow-auto">
{#each filteredRepos as repo, i}
<li>
<button
class="w-full px-3 py-2 text-left hover:bg-slate-700 text-slate-200 {selectedIndex === i ? 'bg-slate-700' : ''}"
on:click={() => selectRepo(repo)}
>
<div class="flex items-center justify-between">
<span class="font-medium">{repo.name}</span>
{#if repo.private}
<span class="text-xs text-slate-400">Private</span>
{/if}
</div>
{#if repo.description}
<p class="text-sm text-slate-400 truncate">{repo.description}</p>
{/if}
</div>
{#if repo.description}
<p class="text-sm text-slate-400 truncate">{repo.description}</p>
</button>
</li>
{/each}
{#if !repoExists}
<li class="px-3 py-2 text-sm text-slate-400">
{#if repoName.length > 0}
<p class="text-orange-400">💡If the repository "{repoName}" doesn't exist, it will be created automatically.</p>
<p class="text-emerald-400">✨ If it's a private repository, you can still enter it manually even if it's not visible in the list.</p>
{:else}
<p>Enter a repository name (new or private) or select from your public repositories</p>
{/if}
</button>
</li>
{/each}
{#if !repoExists}
<li class="px-3 py-2 text-sm text-slate-400">
{#if repoName.length > 0}
<p class="text-orange-400">💡If the repository "{repoName}" doesn't exist, it will be created automatically.</p>
<p class="text-emerald-400">✨ If it's a private repository, you can still enter it manually even if it's not visible in the list.</p>
{:else}
<p>Enter a repository name (new or private) or select from your public repositories</p>
{/if}
</li>
{/if}
</ul>
</div>
</li>
{/if}
</ul>
</div>
{/if}
</div>
{#if repoExists}
<p class="text-sm text-blue-400">
ℹ️ Using existing repository
</p>
{:else if repoName}
<p class="text-sm text-emerald-400">
✨ A new repository will be created if it doesn't exist yet.
</p>
<p class="text-sm text-orange-400">
⚠️ You can push to private repositories, but loading it into Bolt will fail.
</p>
{/if}
</div>
{#if repoExists}
<p class="text-sm text-blue-400">
ℹ️ Using existing repository
</p>
{:else if repoName}
<p class="text-sm text-emerald-400">
✨ A new repository will be created if it doesn't exist yet.
</p>
<p class="text-sm text-orange-400">
⚠️ You can push to private repositories, but loading it into Bolt will fail.
</p>
{/if}
</div>

<div class="space-y-2">
<Label for="branch" class="text-slate-200">
Branch
<span class="text-sm text-slate-400 ml-2">(Usually "main")</span>
</Label>
<Input
type="text"
id="branch"
bind:value={branch}
on:input={onInput}
placeholder="main"
class="bg-slate-800 border-slate-700 text-slate-200 placeholder:text-slate-500"
/>
</div>
<p class="text-sm text-slate-400">
💡 If the branch doesn't exist, it will be created automatically from the default branch.
</p>
<div class="space-y-2">
<Label for="branch" class="text-slate-200">
Branch
<span class="text-sm text-slate-400 ml-2">(Usually "main")</span>
</Label>
<Input
type="text"
id="branch"
bind:value={branch}
on:input={onInput}
placeholder="main"
class="bg-slate-800 border-slate-700 text-slate-200 placeholder:text-slate-500"
/>
</div>
<p class="text-sm text-slate-400">
💡 If the branch doesn't exist, it will be created automatically from the default branch.
</p>
{/if}

<Button
type="submit"
class="w-full bg-blue-600 hover:bg-blue-700 text-white"
disabled={buttonDisabled || isValidatingToken || !githubToken || !repoOwner || !repoName || !branch || isTokenValid === false}
disabled={buttonDisabled || isValidatingToken || !githubToken || !repoOwner || (!isOnboarding && (!repoName || !branch)) || isTokenValid === false}
>
{#if isValidatingToken}
Validating...
{:else if buttonDisabled}
{status}
{:else}
Save Settings
{isOnboarding ? 'Get Started' : 'Save Settings'}
{/if}
</Button>
</form>
Expand Down
7 changes: 4 additions & 3 deletions src/lib/components/ProjectsList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,7 @@
{#if filteredProjects.length === 0}
<div class="flex flex-col items-center justify-center p-4 text-center space-y-6">
<div class="space-y-2">
<p class="text-sm text-slate-400 text-orange-400">No projects found. Create or load an existing project to get started.</p>
</div>
{#if !isBoltSite}
{#if !isBoltSite}
<Button
variant="outline"
class="border-slate-800 hover:bg-slate-800 text-slate-200"
Expand All @@ -133,6 +131,9 @@
Go to bolt.new
</Button>
{/if}
<p class="text-sm text-green-400">💡 No Bolt projects found. Create or load an existing Bolt project to get started.</p>
<p class="text-sm text-green-400">🌟 You can also load any of your public GitHub repositories.</p>
</div>
</div>
{:else}
{#each filteredProjects as project}
Expand Down
18 changes: 16 additions & 2 deletions src/popup/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
let isValidatingToken = false;
let isTokenValid: boolean | null = null;
let validationError: string | null = null;
let hasInitialSettings = false;
async function validateGitHubToken(token: string, username: string): Promise<boolean> {
if (!token) {
Expand Down Expand Up @@ -79,6 +80,7 @@
githubToken = githubSettings.githubToken || "";
repoOwner = githubSettings.repoOwner || "";
projectSettings = githubSettings.projectSettings || {};
hasInitialSettings = Boolean(githubSettings.githubToken && githubSettings.repoOwner);
// Validate existing token and username if they exist
if (githubToken && repoOwner) {
Expand Down Expand Up @@ -155,6 +157,7 @@
}
await chrome.storage.sync.set(settings);
hasInitialSettings = true;
status = "Settings saved successfully!";
hasStatus = true;
checkSettingsValidity();
Expand Down Expand Up @@ -241,12 +244,11 @@
</Card>
</TabsContent>
</Tabs>
{:else if repoOwner}
{:else if hasInitialSettings && repoOwner && githubToken}
<ProjectsList {projectSettings} {repoOwner} {githubToken} currentlyLoadedProjectId={parsedProjectId} isBoltSite={isBoltSite} />
{:else}
<div class="flex flex-col items-center justify-center p-4 text-center space-y-6">
<div class="space-y-2">
<p class="text-sm text-slate-400 text-orange-400">No projects found. Create or load an existing project to get started.</p>
{#if !isBoltSite}
<Button
variant="outline"
Expand All @@ -256,6 +258,18 @@
Go to bolt.new
</Button>
{/if}
<p class="text-sm text-green-400">💡 No Bolt projects found. Create or load an existing Bolt project to get started.</p>
<p class="text-sm text-green-400 pb-4">🌟 You can also load any of your public GitHub repositories by providing your GitHub token and repository owner.</p>
<GitHubSettings
isOnboarding={true}
bind:githubToken
bind:repoOwner
{status}
{isSettingsValid}
buttonDisabled={hasStatus}
onSave={saveSettings}
onInput={checkSettingsValidity}
/>
</div>
</div>
{/if}
Expand Down

0 comments on commit 6d82e30

Please sign in to comment.