Skip to content

Commit 603e5d7

Browse files
committed
feat: add nuxt app
1 parent 50887ef commit 603e5d7

39 files changed

+18528
-53
lines changed

packages/app/.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
node_modules
2+
*.log
3+
dist
4+
.output
5+
.nuxt
6+
.env
7+
.idea/
8+
.data

packages/app/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024-PRESENT Sebastien Chopin<https://github.com/atinux> & Anthony Fu<https://github.com/antfu>
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

packages/app/README.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Share your Open Source Contributions 🤍
2+
3+
Create a website with an RSS feed of your recent GitHub pull requests across the Open Source projects you contribute to.
4+
5+
![atinux-pull-requests](https://github.com/user-attachments/assets/cfa82cc2-51af-4fd4-9012-1f8517dd370f)
6+
7+
Demo: https://prs.atinux.com
8+
9+
[![Deploy to NuxtHub](https://hub.nuxt.com/button.svg)](https://hub.nuxt.com/new?template=my-pull-requests)
10+
11+
## Features
12+
13+
- List the 50 most recent pull requests you've contributed to.
14+
- RSS feed
15+
- Only add your GitHub token to get started
16+
- One click deploy on 275+ locations for free
17+
18+
## Setup
19+
20+
Make sure to install the dependencies with [pnpm](https://pnpm.io/installation#using-corepack):
21+
22+
```bash
23+
pnpm install
24+
```
25+
26+
Copy the `.env.example` file to `.env` and fill in your GitHub token:
27+
28+
```bash
29+
cp .env.example .env
30+
```
31+
32+
Create a GitHub token with no special scope on [GitHub](https://github.com/settings/personal-access-tokens/new) and set it in the `.env` file:
33+
34+
```bash
35+
NUXT_GITHUB_TOKEN=your-github-token
36+
```
37+
38+
## Development Server
39+
40+
Start the development server on `http://localhost:3000`:
41+
42+
```bash
43+
pnpm dev
44+
```
45+
46+
## Production
47+
48+
Build the application for production:
49+
50+
```bash
51+
pnpm build
52+
```
53+
54+
## Deploy
55+
56+
Deploy the application on the Edge with [NuxtHub](https://hub.nuxt.com) on your Cloudflare account:
57+
58+
```bash
59+
npx nuxthub deploy
60+
```
61+
62+
Then checkout your server cache, analaytics and more in the [NuxtHub Admin](https://admin.hub.nuxt.com).
63+
64+
You can also deploy using [Cloudflare Pages CI](https://hub.nuxt.com/docs/getting-started/deploy#cloudflare-pages-ci).
65+
66+
## Credits
67+
68+
This project is inspired by [Anthony Fu](https://github.com/antfu)'s [releases.antfu.me](https://github.com/antfu/releases.antfu.me) project.
69+
70+
## License
71+
72+
[MIT](./LICENSE)

packages/app/app/app.config.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export default defineAppConfig({
2+
ui: {
3+
primary: 'orange',
4+
gray: 'zinc',
5+
},
6+
})

packages/app/app/app.vue

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<script setup>
2+
useHead({
3+
htmlAttrs: {
4+
lang: 'en',
5+
},
6+
link: [
7+
{ rel: 'icon', href: '/favicon.png' },
8+
{ rel: 'icon', type: 'image/svg+xml', href: '/favicon.svg' },
9+
],
10+
})
11+
12+
useSeoMeta({
13+
title: 'Continuous Releases',
14+
description: 'Search repositories on GitHub to list their continuous releases.',
15+
})
16+
</script>
17+
18+
<template>
19+
<div class="flex flex-col min-h-screen">
20+
<div class="flex-1">
21+
<NuxtLoadingIndicator color="orange" />
22+
<NuxtPage />
23+
</div>
24+
25+
<footer class="text-center p-12 opacity-50 hover:opacity-100 focus-within:opacity-100">
26+
Made with ❤️ by <a href="https://github.com/Akryum" target="_blank" class="text-primary">Akryum</a>
27+
</footer>
28+
</div>
29+
</template>
30+
31+
<style lang="postcss">
32+
body {
33+
@apply min-h-screen bg-white dark:bg-gray-900 text-gray-700 dark:text-gray-200 font-sans;
34+
}
35+
</style>
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
<script lang="ts" setup>
2+
import type { RendererObject } from 'marked'
3+
import { marked } from 'marked'
4+
5+
const props = defineProps<{
6+
owner: string
7+
repo: string
8+
}>()
9+
10+
const data = await $fetch('/api/repo/commits', {
11+
query: {
12+
owner: props.owner,
13+
repo: props.repo,
14+
},
15+
})
16+
17+
if (!data) {
18+
throw createError('Could not load Commits')
19+
}
20+
21+
const branch = shallowReactive(data)
22+
23+
const commitsWithRelease = computed(() => branch.target.history.nodes.filter(commit => commit.statusCheckRollup?.contexts.nodes.some(context => context.name === 'Continuous Releases')).map(commit => ({
24+
...commit,
25+
release: commit.statusCheckRollup.contexts.nodes.find(context => context.name === 'Continuous Releases')!,
26+
})))
27+
28+
const selectedCommit = shallowRef<(typeof commitsWithRelease.value)[number] | null>(null)
29+
30+
// Markdown
31+
32+
// Add target to links
33+
const renderer: RendererObject = {
34+
link(originalLink) {
35+
const link = marked.Renderer.prototype.link.call(this, originalLink)
36+
return link.replace('<a', '<a target=\'_blank\' rel=\'noreferrer\' ')
37+
},
38+
}
39+
marked.use({ renderer })
40+
41+
// Pagination
42+
43+
const fetching = ref(false)
44+
const fetchMoreForceDisabled = ref(!commitsWithRelease.value.length)
45+
46+
async function fetchMore() {
47+
if (!branch.target.history.pageInfo.hasNextPage) {
48+
return
49+
}
50+
51+
if (fetching.value) {
52+
return
53+
}
54+
55+
try {
56+
fetching.value = true
57+
58+
const cursor = branch.target.history.pageInfo.endCursor
59+
60+
const result = await $fetch('/api/repo/commits', {
61+
query: {
62+
owner: props.owner,
63+
repo: props.repo,
64+
cursor,
65+
},
66+
})
67+
68+
const count = commitsWithRelease.value.length
69+
70+
branch.target = {
71+
...branch.target,
72+
history: {
73+
...branch.target.history,
74+
nodes: [
75+
...branch.target.history.nodes,
76+
...result.target.history.nodes,
77+
],
78+
pageInfo: result.target.history.pageInfo,
79+
},
80+
}
81+
82+
if (count === commitsWithRelease.value.length) {
83+
fetchMoreForceDisabled.value = true
84+
}
85+
}
86+
finally {
87+
fetching.value = false
88+
}
89+
}
90+
</script>
91+
92+
<template>
93+
<div class="flex flex-col gap-6">
94+
<div class="text-center flex justify-center items-center gap-1 opacity-80">
95+
Continuous Releases from
96+
<UIcon name="i-ph-git-branch" />
97+
{{ branch.name }}
98+
</div>
99+
100+
<div class="flex flex-col gap-2">
101+
<div
102+
v-for="commit of commitsWithRelease"
103+
:key="commit.id"
104+
class="px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg cursor-pointer"
105+
:class="{
106+
'bg-gray-100 dark:bg-gray-800': selectedCommit === commit,
107+
}"
108+
aria-role="button"
109+
@click="selectedCommit = commit"
110+
>
111+
<div class="flex items-center gap-2">
112+
<UIcon name="i-ph-git-commit" class="opacity-50 flex-none" />
113+
<span class="truncate">{{ commit.message }}</span>
114+
<span class="opacity-50 flex-none">
115+
{{ useTimeAgo(commit.authoredDate) }}
116+
</span>
117+
<span class="flex-1" />
118+
<UButton
119+
:to="commit.url"
120+
target="_blank"
121+
color="gray"
122+
size="2xs"
123+
aria-label="View Commit"
124+
:ui="{
125+
font: 'font-mono',
126+
}"
127+
@click.stop
128+
>
129+
{{ commit.abbreviatedOid }}
130+
</UButton>
131+
</div>
132+
</div>
133+
</div>
134+
135+
<div
136+
v-if="branch.target.history.pageInfo.hasNextPage && !fetchMoreForceDisabled"
137+
class="flex justify-center"
138+
>
139+
<UButton
140+
color="gray"
141+
:loading="fetching"
142+
@click="fetchMore()"
143+
>
144+
Load More
145+
</UButton>
146+
</div>
147+
148+
<div
149+
v-if="!commitsWithRelease.length"
150+
class="flex flex-col items-center gap-4 border border-gray-100 dark:border-gray-800 rounded-xl p-8"
151+
>
152+
<UIcon name="i-ph-crane-tower-light" class="text-6xl opacity-50" />
153+
<p class="text-center text-lg">
154+
No Continuous Releases found
155+
</p>
156+
<p class="text-center">
157+
Setup continuous releases with <a href="https://github.com/stackblitz-labs/pkg.pr.new" target="_blank" class="text-primary">pkg.pr.new</a> first!
158+
</p>
159+
</div>
160+
161+
<!-- Commit sidepane -->
162+
<USlideover
163+
:model-value="!!selectedCommit"
164+
:ui="{
165+
width: 'w-screen max-w-[800px]',
166+
}"
167+
@update:model-value="selectedCommit = null"
168+
>
169+
<div
170+
v-if="selectedCommit"
171+
class="p-4 flex flex-col items-stretch gap-4 overflow-auto"
172+
>
173+
<div class="flex items-center gap-2">
174+
<UIcon name="i-ph-git-commit" class="opacity-50 flex-none" />
175+
<span>{{ selectedCommit.message }}</span>
176+
<span class="opacity-50 flex-none">
177+
{{ useTimeAgo(selectedCommit.authoredDate) }}
178+
</span>
179+
<span class="flex-1" />
180+
<UButton
181+
:to="selectedCommit.url"
182+
target="_blank"
183+
color="gray"
184+
size="2xs"
185+
aria-label="View Commit"
186+
@click.stop
187+
>
188+
{{ selectedCommit.abbreviatedOid }}
189+
</UButton>
190+
</div>
191+
192+
<div
193+
class="max-w-full p-4 border border-gray-100 dark:border-gray-800 rounded-lg prose dark:prose-invert"
194+
v-html="marked(selectedCommit.release.text)"
195+
/>
196+
</div>
197+
</USlideover>
198+
</div>
199+
</template>
200+
201+
<style>
202+
details {
203+
@apply my-2;
204+
}
205+
206+
summary {
207+
@apply cursor-pointer;
208+
}
209+
</style>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<script lang="ts" setup>
2+
defineProps<{
3+
owner: string
4+
name: string
5+
avatar?: string
6+
}>()
7+
</script>
8+
9+
<template>
10+
<UButton
11+
:to="`/${owner}/${name}`"
12+
class="w-full"
13+
size="lg"
14+
color="gray"
15+
variant="ghost"
16+
>
17+
<UAvatar
18+
:src="avatar"
19+
:alt="name"
20+
size="sm"
21+
/>
22+
23+
<div class="font-mono">
24+
<span>{{ owner }}</span>
25+
<span class="opacity-50">/</span>
26+
<span>{{ name }}</span>
27+
</div>
28+
</UButton>
29+
</template>

0 commit comments

Comments
 (0)