generated from abhagsain/remix-tailwind-starter
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: ✅ add search for release & caching on CF workers
- Loading branch information
Showing
24 changed files
with
2,911 additions
and
924 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,14 @@ | ||
{ | ||
"extends": ["@remix-run/eslint-config", "@remix-run/eslint-config/node"] | ||
} | ||
"extends": [ | ||
"@remix-run/eslint-config", | ||
"@remix-run/eslint-config/node" | ||
], | ||
"settings": { | ||
"files": [ | ||
"**/*.js", | ||
"**/*.jsx", | ||
"**/*.ts", | ||
"**/*.tsx" | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import { marked } from "marked"; | ||
import type { IChangeLog, SearchFormData } from "./types"; | ||
import { getJSON } from "./utils"; | ||
const WORKER_ENDPOINT = process.env.WORKER_URL || "http://localhost:8787/api"; | ||
|
||
export const getNameAndURLFromPackageName = async (name: string) => { | ||
const API_ENDPOINT = `${WORKER_ENDPOINT}/package/${name}`; | ||
const res = await fetch(API_ENDPOINT).then((res) => res.json()); | ||
const { ownerName, repoName } = res; | ||
return { ownerName, repoName }; | ||
}; | ||
|
||
export const getReleaseTags = async ( | ||
ownerName: string, | ||
repoName: string, | ||
perPage = 100, | ||
page = 1 | ||
): Promise<IChangeLog[] | Response> => { | ||
const URL = `${WORKER_ENDPOINT}/repos/${ownerName}/${repoName}/tags?per_page=${perPage}&page=${page}`; | ||
const data = await getJSON(URL); | ||
return data; | ||
}; | ||
|
||
export const getReleaseInfo = async ( | ||
name: string, | ||
versions: SearchFormData["versions"] | ||
) => { | ||
const { ownerName, repoName } = (await getNameAndURLFromPackageName( | ||
name | ||
)) as { ownerName: string; repoName: string }; | ||
const versionPromise = versions.map((version) => | ||
getTagByVersion(ownerName, repoName, version) | ||
); | ||
const result = await Promise.allSettled(versionPromise).then((res) => { | ||
return res | ||
.filter((r) => r.status === "fulfilled") | ||
.map((r) => | ||
r.status === "fulfilled" | ||
? { | ||
...(r.value as IChangeLog), | ||
html: marked((r.value as IChangeLog).body), | ||
} | ||
: undefined | ||
); | ||
}); | ||
const releaseTagsList = (await getReleaseTags( | ||
ownerName, | ||
repoName | ||
)) as IChangeLog[]; | ||
return { | ||
ownerName, | ||
repoName, | ||
releaseTagsList, | ||
changeLogs: result, | ||
}; | ||
}; | ||
|
||
export const getChangelogList = async (values: SearchFormData[]) => { | ||
const releases = await Promise.all( | ||
values.map(({ name, versions }) => getReleaseInfo(name, versions)) | ||
); | ||
return releases; | ||
}; | ||
|
||
export const getTagByVersion = async ( | ||
authorName: string, | ||
repoName: string, | ||
tagName: string | ||
): Promise<IChangeLog> => { | ||
const API_URL = `${WORKER_ENDPOINT}/repos/${authorName}/${repoName}/releases/tags/${tagName}`; | ||
return getJSON(API_URL); | ||
}; |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import type { IChangeLog } from "../types"; | ||
|
||
interface IChangelogProps { | ||
changeLog?: IChangeLog; | ||
} | ||
|
||
const Changelog = ({ changeLog }: IChangelogProps) => { | ||
if (!changeLog) { | ||
return ( | ||
<div className="flex items-center justify-center w-full max-w-3xl"> | ||
<h3>Couldn't find info about this release </h3> | ||
</div> | ||
); | ||
} | ||
|
||
const { author, name, tag_name, published_at } = changeLog; | ||
const formattedDate = new Date(published_at).toLocaleDateString(); | ||
return ( | ||
<article> | ||
<h3>{name || tag_name} </h3> | ||
<div className="flex items-center space-x-1 text-white/60"> | ||
<img src={author.avatar_url} alt="" className="w-5 h-5 m-0" /> | ||
<p className="my-1">{author.login}</p> | ||
<p className="my-1">released this {formattedDate}</p> | ||
</div> | ||
<div dangerouslySetInnerHTML={{ __html: changeLog?.html }} /> | ||
</article> | ||
); | ||
}; | ||
|
||
export default Changelog; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import useChangeLogState from "../hooks/useChangelogState"; | ||
import type { AutocompleteOption, LoaderData } from "../types"; | ||
import Changelog from "./Changelog"; | ||
import MultiSelect from "./MultiSelect/MultiSelect"; | ||
|
||
const ChangeLogList = ({ changeLogList }: { changeLogList: LoaderData }) => { | ||
const { setSelectedReleases, updateURLSearchParams } = useChangeLogState(); | ||
|
||
const scrollToItem = (name: string) => { | ||
const item = document.getElementById(`#${name.toLowerCase()}`); | ||
item?.scrollIntoView(true); | ||
}; | ||
|
||
const renderNav = () => { | ||
if (changeLogList.length <= 1) return null; | ||
return ( | ||
<nav className="sticky top-0 z-10 flex flex-wrap px-8 space-x-4 backdrop-blur"> | ||
{changeLogList.map((release) => ( | ||
<div | ||
key={`nav-${release.repoName}`} | ||
onClick={() => scrollToItem(release.repoName)} | ||
className="py-2 text-lg cursor-pointer hover:text-cyan-400" | ||
> | ||
{release.repoName} | ||
</div> | ||
))} | ||
</nav> | ||
); | ||
}; | ||
|
||
return ( | ||
<div className="space-y-4"> | ||
{renderNav()} | ||
<section className="flex flex-col justify-start space-y-10"> | ||
{changeLogList?.map((changeLog) => { | ||
const repoName = changeLog.repoName; | ||
const options = changeLog.releaseTagsList.map((tag) => ({ | ||
label: tag.name, | ||
value: tag.name, | ||
})); | ||
const defaultChangeLogVersions = [ | ||
...changeLog.changeLogs.map((log) => ({ | ||
label: log?.tag_name, | ||
value: log?.tag_name, | ||
})), | ||
]; | ||
|
||
return changeLog.changeLogs ? ( | ||
<div id={`#${changeLog.repoName.toLowerCase()}`}> | ||
<div className="flex items-center justify-between px-8 space-x-4"> | ||
<div className="flex items-center"> | ||
<h2 className="my-4">{repoName}</h2> | ||
</div> | ||
<div className="flex items-center space-x-3"> | ||
<MultiSelect | ||
isMulti | ||
name="versions" | ||
id="versions" | ||
options={options} | ||
onChange={(values) => { | ||
setSelectedReleases(values as AutocompleteOption[]); | ||
}} | ||
defaultValue={defaultChangeLogVersions} | ||
isSearchable | ||
/> | ||
<button | ||
type="submit" | ||
onClick={() => { | ||
updateURLSearchParams(repoName); | ||
}} | ||
> | ||
Search | ||
</button> | ||
</div> | ||
</div> | ||
<div className="grid grid-cols-1 gap-4 px-8 lg:grid-cols-2"> | ||
{changeLog.changeLogs.map((release) => ( | ||
<Changelog changeLog={release} key={release?.node_id} /> | ||
))} | ||
</div> | ||
</div> | ||
) : null; | ||
})} | ||
</section> | ||
</div> | ||
); | ||
}; | ||
|
||
export default ChangeLogList; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
const Label = ({ | ||
children, | ||
htmlFor, | ||
...args | ||
}: { | ||
children: string; | ||
htmlFor: string; | ||
}) => ( | ||
<label | ||
htmlFor={htmlFor} | ||
className="block text-sm font-medium text-gray-700 dark:text-white/95" | ||
{...args} | ||
> | ||
{children} | ||
</label> | ||
); | ||
|
||
export default Label; |
Oops, something went wrong.