Skip to content

Commit

Permalink
Merge pull request #27 from dwightjack/arrowjs
Browse files Browse the repository at this point in the history
Migrate to arrowjs
  • Loading branch information
dwightjack authored Jul 25, 2023
2 parents 32317ad + e7d1bf6 commit ea87a57
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 45 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
}
},
{
"files": ["src/**/*.js"],
"files": ["src/**/*.mjs"],
"env": {
"browser": true,
"es6": true
Expand Down
105 changes: 61 additions & 44 deletions src/js/main.mjs
Original file line number Diff line number Diff line change
@@ -1,66 +1,83 @@
import { app, h, text } from 'https://cdn.skypack.dev/hyperapp@2';
//@ts-check
import { reactive, html } from 'https://esm.sh/@arrow-js/core';

const initialState = {
status: 'idle',
repos: [],
};
/**
* @typedef {Object} Repository
* @property {string} name
* @property {string} topics
* @property {string} homepageUrl
* @property {string} description
* @property {string} url
*/

const SetStatus = (state, status) => ({ ...state, status });
/**
* @typedef {Object} Data
* @property {'idle' | 'loading' | 'loaded' | 'error'} status
* @property {Repository[]} repos
*/

const GotProjects = (state, repos = []) => ({
...SetStatus(state, 'loaded'),
repos,
/**
* @type {Data}
*/
const data = reactive({
status: 'idle',
repos: [],
});

function branch(prop, branches) {
return branches[prop] || branches.default;
function branch(branches) {
return branches[data.status] || branches.default;
}

async function FetchProjects(dispatch) {
dispatch(SetStatus, 'loading');
async function fetchProjects() {
data.status = 'loading';

try {
const response = await fetch('/.netlify/functions/fetch-projects');
if (!response.ok) {
throw response;
}
dispatch(GotProjects, await response.json());
Object.assign(data, {
status: 'loaded',
repos: await response.json(),
});
} catch (error) {
console.error(error);
dispatch(SetStatus, 'error');
Object.assign(data, {
status: 'error',
repos: [],
});
}
}

function Link(href, txt) {
return h('a', { target: '_blank', href }, text(txt));
/**
*
* @param {Repository} repository
* @returns
*/
function RepoItem({ name, topics, homepageUrl, description, url }) {
return html`<article class="card">
<header>
<h2>
<a href="${homepageUrl}" target="_blank">${name}</a>
</h2>
</header>
<p>
${description}<br />
<small>
<a href="${url}" target="_blank">GitHub</a>
</small>
</p>
<p>${topics.map((txt) => html`<span class="label">${txt}</span>`)}</p>
</article>`.key(url);
}

function Label(txt) {
return h('span', { class: 'label' }, text(txt));
}
const template = html`${() =>
branch({
loading: html`<p>Loading...</p>`,
loaded: data.repos.map(RepoItem),
error: html`<p>Error!</p>`,
})}`;

function RepoItem({ name, topics, homepageUrl, description, url }) {
return h('article', { class: 'card' }, [
h('header', {}, h('h2', {}, Link(homepageUrl, name))),
h('p', {}, [
h('div', {}, text(description)),
h('small', {}, Link(url, 'GitHub')),
]),
h('p', { class: 'cluster' }, topics.map(Label)),
]);
}
template(document.getElementById('main'));

app({
init: [initialState, [FetchProjects]],
node: document.getElementById('main'),
view: ({ repos, status }) =>
h(
'main',
{},
branch(status, {
loading: h('p', {}, text('Loading...')),
loaded: h('div', {}, repos.map(RepoItem)),
error: h('p', {}, text('Error')),
}),
),
});
fetchProjects();

0 comments on commit ea87a57

Please sign in to comment.