mirror of
https://github.com/Xevion/xevion.dev.git
synced 2026-01-31 04:26:43 -06:00
refactor: use GitHub activity for project sorting instead of update timestamp
This commit is contained in:
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"db_name": "PostgreSQL",
|
"db_name": "PostgreSQL",
|
||||||
"query": "\n SELECT \n p.id, \n p.slug, \n p.name,\n p.short_description,\n p.description, \n p.status as \"status: super::ProjectStatus\", \n p.github_repo, \n p.demo_url, \n p.last_github_activity, \n p.created_at, \n p.updated_at\n FROM projects p\n JOIN project_tags pt ON p.id = pt.project_id\n WHERE pt.tag_id = $1\n ORDER BY p.updated_at DESC\n ",
|
"query": "\n SELECT \n p.id, \n p.slug, \n p.name,\n p.short_description,\n p.description, \n p.status as \"status: super::ProjectStatus\", \n p.github_repo, \n p.demo_url, \n p.last_github_activity, \n p.created_at, \n p.updated_at\n FROM projects p\n JOIN project_tags pt ON p.id = pt.project_id\n WHERE pt.tag_id = $1\n ORDER BY COALESCE(p.last_github_activity, p.created_at) DESC\n ",
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
{
|
{
|
||||||
@@ -90,5 +90,5 @@
|
|||||||
false
|
false
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"hash": "73404037b3f04ace5f775906ed25d4c572647889dc0185aed652038447ef9642"
|
"hash": "3401838a054f29a17d96086529b7222026aafa8a385615129eb0d407e44faa9c"
|
||||||
}
|
}
|
||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"db_name": "PostgreSQL",
|
"db_name": "PostgreSQL",
|
||||||
"query": "\n SELECT\n id,\n slug,\n name,\n short_description,\n description,\n status as \"status: ProjectStatus\",\n github_repo,\n demo_url,\n last_github_activity,\n created_at,\n updated_at\n FROM projects\n ORDER BY updated_at DESC\n ",
|
"query": "\n SELECT\n id,\n slug,\n name,\n short_description,\n description,\n status as \"status: ProjectStatus\",\n github_repo,\n demo_url,\n last_github_activity,\n created_at,\n updated_at\n FROM projects\n ORDER BY COALESCE(last_github_activity, created_at) DESC\n ",
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
{
|
{
|
||||||
@@ -88,5 +88,5 @@
|
|||||||
false
|
false
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"hash": "7210d993016792490832230c09ed3c4dfc1a6292fcc9c16ded0b182b9952b7ce"
|
"hash": "4a2a394398d4597d2366023baad3327cc50ed2c914abe1293644cc860df74d34"
|
||||||
}
|
}
|
||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"db_name": "PostgreSQL",
|
"db_name": "PostgreSQL",
|
||||||
"query": "\n SELECT\n id,\n slug,\n name,\n short_description,\n description,\n status as \"status: ProjectStatus\",\n github_repo,\n demo_url,\n last_github_activity,\n created_at,\n updated_at\n FROM projects\n WHERE status != 'hidden'\n ORDER BY updated_at DESC\n ",
|
"query": "\n SELECT\n id,\n slug,\n name,\n short_description,\n description,\n status as \"status: ProjectStatus\",\n github_repo,\n demo_url,\n last_github_activity,\n created_at,\n updated_at\n FROM projects\n WHERE status != 'hidden'\n ORDER BY COALESCE(last_github_activity, created_at) DESC\n ",
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
{
|
{
|
||||||
@@ -88,5 +88,5 @@
|
|||||||
false
|
false
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"hash": "92641a97d3f5329df38e2ecb456b1f43392b34bba0b286ab9bd75a8207354fea"
|
"hash": "d851d8d7117d3cfcd8c50304d60565cd2cc275e2776929d660f9351dad5b418f"
|
||||||
}
|
}
|
||||||
@@ -27,6 +27,7 @@ check:
|
|||||||
{ name: "eslint", cmd: ["bun", "run", "--cwd", "web", "lint"] },
|
{ name: "eslint", cmd: ["bun", "run", "--cwd", "web", "lint"] },
|
||||||
{ name: "svelte-check", cmd: ["bun", "run", "--cwd", "web", "check"] },
|
{ name: "svelte-check", cmd: ["bun", "run", "--cwd", "web", "check"] },
|
||||||
{ name: "clippy", cmd: ["cargo", "clippy", "--all-targets"] },
|
{ name: "clippy", cmd: ["cargo", "clippy", "--all-targets"] },
|
||||||
|
{ name: "sqlx-prepare", cmd: ["cargo", "sqlx", "prepare", "--check"] },
|
||||||
{ name: "rustfmt", cmd: ["cargo", "fmt", "--check"] },
|
{ name: "rustfmt", cmd: ["cargo", "fmt", "--check"] },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
+5
-1
@@ -48,7 +48,11 @@ pub fn print_project(project: &ApiAdminProject) {
|
|||||||
println!(" {} {}", dim.paint("Tags:"), tags.join(", "));
|
println!(" {} {}", dim.paint("Tags:"), tags.join(", "));
|
||||||
}
|
}
|
||||||
|
|
||||||
println!(" {} {}", dim.paint("Updated:"), project.updated_at);
|
println!(
|
||||||
|
" {} {}",
|
||||||
|
dim.paint("Last Activity:"),
|
||||||
|
project.last_activity
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Print a list of projects in table format
|
/// Print a list of projects in table format
|
||||||
|
|||||||
+11
-10
@@ -56,10 +56,8 @@ pub struct ApiAdminProject {
|
|||||||
pub demo_url: Option<String>,
|
pub demo_url: Option<String>,
|
||||||
#[serde(rename = "createdAt")]
|
#[serde(rename = "createdAt")]
|
||||||
pub created_at: String, // ISO 8601
|
pub created_at: String, // ISO 8601
|
||||||
#[serde(rename = "updatedAt")]
|
#[serde(rename = "lastActivity")]
|
||||||
pub updated_at: String, // ISO 8601
|
pub last_activity: String, // ISO 8601
|
||||||
#[serde(rename = "lastGithubActivity", skip_serializing_if = "Option::is_none")]
|
|
||||||
pub last_github_activity: Option<String>, // ISO 8601
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DbProject {
|
impl DbProject {
|
||||||
@@ -91,6 +89,12 @@ impl DbProject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_api_admin_project(&self, tags: Vec<DbTag>) -> ApiAdminProject {
|
pub fn to_api_admin_project(&self, tags: Vec<DbTag>) -> ApiAdminProject {
|
||||||
|
let last_activity = self
|
||||||
|
.last_github_activity
|
||||||
|
.unwrap_or(self.created_at)
|
||||||
|
.format(&Rfc3339)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
ApiAdminProject {
|
ApiAdminProject {
|
||||||
project: self.to_api_project(),
|
project: self.to_api_project(),
|
||||||
tags: tags.into_iter().map(|t| t.to_api_tag()).collect(),
|
tags: tags.into_iter().map(|t| t.to_api_tag()).collect(),
|
||||||
@@ -99,10 +103,7 @@ impl DbProject {
|
|||||||
github_repo: self.github_repo.clone(),
|
github_repo: self.github_repo.clone(),
|
||||||
demo_url: self.demo_url.clone(),
|
demo_url: self.demo_url.clone(),
|
||||||
created_at: self.created_at.format(&Rfc3339).unwrap(),
|
created_at: self.created_at.format(&Rfc3339).unwrap(),
|
||||||
updated_at: self.updated_at.format(&Rfc3339).unwrap(),
|
last_activity,
|
||||||
last_github_activity: self
|
|
||||||
.last_github_activity
|
|
||||||
.map(|dt| dt.format(&Rfc3339).unwrap()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,7 +165,7 @@ pub async fn get_public_projects(pool: &PgPool) -> Result<Vec<DbProject>, sqlx::
|
|||||||
updated_at
|
updated_at
|
||||||
FROM projects
|
FROM projects
|
||||||
WHERE status != 'hidden'
|
WHERE status != 'hidden'
|
||||||
ORDER BY updated_at DESC
|
ORDER BY COALESCE(last_github_activity, created_at) DESC
|
||||||
"#
|
"#
|
||||||
)
|
)
|
||||||
.fetch_all(pool)
|
.fetch_all(pool)
|
||||||
@@ -203,7 +204,7 @@ pub async fn get_all_projects_admin(pool: &PgPool) -> Result<Vec<DbProject>, sql
|
|||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
FROM projects
|
FROM projects
|
||||||
ORDER BY updated_at DESC
|
ORDER BY COALESCE(last_github_activity, created_at) DESC
|
||||||
"#
|
"#
|
||||||
)
|
)
|
||||||
.fetch_all(pool)
|
.fetch_all(pool)
|
||||||
|
|||||||
+1
-1
@@ -314,7 +314,7 @@ pub async fn get_projects_for_tag(
|
|||||||
FROM projects p
|
FROM projects p
|
||||||
JOIN project_tags pt ON p.id = pt.project_id
|
JOIN project_tags pt ON p.id = pt.project_id
|
||||||
WHERE pt.tag_id = $1
|
WHERE pt.tag_id = $1
|
||||||
ORDER BY p.updated_at DESC
|
ORDER BY COALESCE(p.last_github_activity, p.created_at) DESC
|
||||||
"#,
|
"#,
|
||||||
tag_id
|
tag_id
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -27,8 +27,7 @@ export interface AdminProject {
|
|||||||
githubRepo?: string | null;
|
githubRepo?: string | null;
|
||||||
demoUrl?: string | null;
|
demoUrl?: string | null;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
updatedAt: string;
|
lastActivity: string;
|
||||||
lastGithubActivity?: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CreateProjectData {
|
export interface CreateProjectData {
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
{project.name}
|
{project.name}
|
||||||
</h3>
|
</h3>
|
||||||
<span class="shrink-0 sm:text-[0.83rem] text-zinc-600 dark:text-zinc-300">
|
<span class="shrink-0 sm:text-[0.83rem] text-zinc-600 dark:text-zinc-300">
|
||||||
{formatDate(project.updatedAt)}
|
{formatDate(project.lastActivity)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<p
|
<p
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export interface MockProject {
|
|||||||
description: string;
|
description: string;
|
||||||
url: string;
|
url: string;
|
||||||
tags: MockProjectTag[];
|
tags: MockProjectTag[];
|
||||||
updatedAt: string;
|
lastActivity: string;
|
||||||
clockIconSvg?: string; // Pre-rendered clock icon for "Updated" text
|
clockIconSvg?: string; // Pre-rendered clock icon for "Updated" text
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ export const MOCK_PROJECTS: MockProject[] = [
|
|||||||
{ name: "SvelteKit", icon: "simple-icons:svelte", color: "f43f5e" },
|
{ name: "SvelteKit", icon: "simple-icons:svelte", color: "f43f5e" },
|
||||||
{ name: "PostgreSQL", icon: "cib:postgresql", color: "3b82f6" },
|
{ name: "PostgreSQL", icon: "cib:postgresql", color: "3b82f6" },
|
||||||
],
|
],
|
||||||
updatedAt: "2026-01-06T22:12:37Z",
|
lastActivity: "2026-01-06T22:12:37Z",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "2",
|
id: "2",
|
||||||
@@ -40,7 +40,7 @@ export const MOCK_PROJECTS: MockProject[] = [
|
|||||||
{ name: "CLI", icon: "lucide:terminal", color: "a1a1aa" },
|
{ name: "CLI", icon: "lucide:terminal", color: "a1a1aa" },
|
||||||
{ name: "Analytics", icon: "lucide:bar-chart-3", color: "10b981" },
|
{ name: "Analytics", icon: "lucide:bar-chart-3", color: "10b981" },
|
||||||
],
|
],
|
||||||
updatedAt: "2026-01-06T06:01:27Z",
|
lastActivity: "2026-01-06T06:01:27Z",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "3",
|
id: "3",
|
||||||
@@ -53,7 +53,7 @@ export const MOCK_PROJECTS: MockProject[] = [
|
|||||||
{ name: "NPM", icon: "simple-icons:npm", color: "ec4899" },
|
{ name: "NPM", icon: "simple-icons:npm", color: "ec4899" },
|
||||||
{ name: "Graphics", icon: "lucide:image", color: "a855f7" },
|
{ name: "Graphics", icon: "lucide:image", color: "a855f7" },
|
||||||
],
|
],
|
||||||
updatedAt: "2026-01-05T20:23:07Z",
|
lastActivity: "2026-01-05T20:23:07Z",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "4",
|
id: "4",
|
||||||
@@ -67,7 +67,7 @@ export const MOCK_PROJECTS: MockProject[] = [
|
|||||||
{ name: "Desktop", icon: "lucide:monitor", color: "6366f1" },
|
{ name: "Desktop", icon: "lucide:monitor", color: "6366f1" },
|
||||||
{ name: "Media", icon: "lucide:video", color: "f43f5e" },
|
{ name: "Media", icon: "lucide:video", color: "f43f5e" },
|
||||||
],
|
],
|
||||||
updatedAt: "2026-01-05T05:09:09Z",
|
lastActivity: "2026-01-05T05:09:09Z",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "5",
|
id: "5",
|
||||||
@@ -80,7 +80,7 @@ export const MOCK_PROJECTS: MockProject[] = [
|
|||||||
{ name: "Next.js", icon: "simple-icons:nextdotjs", color: "a1a1aa" },
|
{ name: "Next.js", icon: "simple-icons:nextdotjs", color: "a1a1aa" },
|
||||||
{ name: "Networking", icon: "lucide:network", color: "0ea5e9" },
|
{ name: "Networking", icon: "lucide:network", color: "0ea5e9" },
|
||||||
],
|
],
|
||||||
updatedAt: "2026-01-05T10:36:55Z",
|
lastActivity: "2026-01-05T10:36:55Z",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "6",
|
id: "6",
|
||||||
@@ -93,6 +93,6 @@ export const MOCK_PROJECTS: MockProject[] = [
|
|||||||
{ name: "System", icon: "lucide:settings-2", color: "a1a1aa" },
|
{ name: "System", icon: "lucide:settings-2", color: "a1a1aa" },
|
||||||
{ name: "Cross-platform", icon: "lucide:globe", color: "22c55e" },
|
{ name: "Cross-platform", icon: "lucide:globe", color: "22c55e" },
|
||||||
],
|
],
|
||||||
updatedAt: "2026-01-01T00:34:09Z",
|
lastActivity: "2026-01-01T00:34:09Z",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -128,7 +128,7 @@
|
|||||||
<th
|
<th
|
||||||
class="px-4 py-3 text-left text-xs font-medium text-admin-text-muted"
|
class="px-4 py-3 text-left text-xs font-medium text-admin-text-muted"
|
||||||
>
|
>
|
||||||
Updated
|
Last Activity
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
class="px-4 py-3 text-right text-xs font-medium text-admin-text-muted"
|
class="px-4 py-3 text-right text-xs font-medium text-admin-text-muted"
|
||||||
@@ -168,7 +168,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-4 py-3 text-admin-text-secondary text-sm">
|
<td class="px-4 py-3 text-admin-text-secondary text-sm">
|
||||||
{formatDate(project.updatedAt)}
|
{formatDate(project.lastActivity)}
|
||||||
</td>
|
</td>
|
||||||
<td class="px-4 py-3 text-right">
|
<td class="px-4 py-3 text-right">
|
||||||
<div class="flex justify-end gap-2">
|
<div class="flex justify-end gap-2">
|
||||||
|
|||||||
Reference in New Issue
Block a user