Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/live markdown editor #276

Merged
merged 57 commits into from
Nov 3, 2024
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
c2e1830
feat: OIDC周りの環境変数を定義
yupix Sep 25, 2024
5e99477
feat: markdown editorを作るうえで必要になる依存関係を追加
yupix Sep 25, 2024
2e70564
fix: トップページの読み込みに失敗する
yupix Sep 25, 2024
8e725b7
feat: 認証周りを整備
yupix Sep 25, 2024
1befc45
refactor: ディレクトリ構造の変更
yupix Sep 25, 2024
af71766
chore: wip
yupix Sep 25, 2024
c4dbc0f
feat: Fileのモデル作った
yupix Oct 1, 2024
c9d6e0f
feat(deps): s3用のライブラリを追加
yupix Oct 1, 2024
7499f39
feat: ファイルアップロード用のhandlerを作成
yupix Oct 1, 2024
59d9bc1
refactor: 変数名を変更
yupix Oct 1, 2024
a1299bb
feat: preview用のルートを定義
yupix Oct 1, 2024
518d26f
feat: 記事のエディター(仮)を作成
yupix Oct 1, 2024
2a9bb87
featr: 型付いてないものに型を付けた
yupix Oct 4, 2024
663bc89
feat: エディターとして使うライブラリを依存関係に追加
yupix Oct 4, 2024
551bec5
feat: デザインを改善、新記事作成用のページを追加
yupix Oct 4, 2024
7846e1d
chore: デザインの修正
yupix Oct 4, 2024
0327c48
chore: placeholderを追加
yupix Oct 4, 2024
92b2399
chore: エディターのデザインを調整
yupix Oct 4, 2024
63fc732
feat: タイトル入力ができるように
yupix Oct 4, 2024
8417bf3
feat: follower followingの概念を追加
yupix Oct 4, 2024
db82a3d
refactor: rootからheaderとfooterを分離、各layoutにて個別に設定するように
yupix Oct 4, 2024
1428693
refactor: 新記事作成ページでは独自のheaderを持ちたいのでレイアウトを適応しないように
yupix Oct 4, 2024
5aa923c
feat: アバターをアップロードできるように
yupix Oct 4, 2024
9094b18
chore: UserスキーマにavatarUrlを追加
yupix Oct 4, 2024
1e31250
feat: navbarにユーザを表示できるように
yupix Oct 4, 2024
44f61a4
feat: メニューに表示するために各レイアウトでユーザを取得するように
yupix Oct 4, 2024
4a9a7fc
feat: メニューに表示するために各レイアウトでユーザを取得するように
yupix Oct 4, 2024
c8ef31d
chore: デザインの調整
yupix Oct 4, 2024
f0849f1
Merge branch 'feat/live-markdown-editor' of github.com:AkariNext/www.…
yupix Oct 4, 2024
04126b8
feat: buildのtargetをES2023に変更
yupix Oct 4, 2024
f326386
chore: 要らないrouteを削除
yupix Oct 4, 2024
eb075d7
chore: コードを整形
yupix Oct 4, 2024
f0a7a0c
fix: .env.exampleをprismaに合わせて修正
yupix Oct 4, 2024
1d44c32
ci: 今の.envに合わせる
sousuke0422 Oct 4, 2024
228a1df
chore: .env.exampleでexample.comを使う
sousuke0422 Oct 4, 2024
fc7c4ac
chore: 部分的にauth.akarinext.org
sousuke0422 Oct 4, 2024
4e58b77
ci: cat eofを使う
sousuke0422 Oct 4, 2024
825035d
feat(deps): 依存関係の更新
yupix Oct 30, 2024
0deb13a
feat: ファイルの作成・更新日時を追加
yupix Oct 30, 2024
3a48ab0
chore: エディターのスタイルを調整
yupix Oct 30, 2024
73b118b
feat: blog->article
yupix Oct 30, 2024
1749202
feat: ファイルのアップロードに対応
yupix Oct 30, 2024
32dfe8c
feat: 複数形の方が正しいカラムの名前を変更
yupix Oct 30, 2024
d7a5220
feat: validation用にzodとconformを追加
yupix Oct 30, 2024
0fd8470
feat: Loaderを追加
yupix Oct 30, 2024
4f1d3d6
feat: editとnewを統一
yupix Oct 30, 2024
c21f65d
Merge branch 'feat/live-markdown-editor' of github.com:AkariNext/www.…
yupix Oct 30, 2024
1494cbc
feat(deps): 絵文字選択用に emoji-picker-reactを追加
yupix Oct 30, 2024
9f03a19
chore: 依存関係のバージョンを微調整
yupix Nov 2, 2024
b958c5c
feat: dropdown コンポーネントを追加
yupix Nov 2, 2024
1460d7f
chore: wip
yupix Nov 2, 2024
ceb4735
chore: format code
yupix Nov 2, 2024
4001f7c
chore: .ideaを追加
yupix Nov 2, 2024
f573513
feat: 記事作成用のルートを追加
yupix Nov 2, 2024
5f8b99d
feat: postのschemaにemojiを追加
yupix Nov 2, 2024
f130446
feat: emojiを選択できるように
yupix Nov 2, 2024
bbbcf74
feat: アバターをクリックしたときのドロップダウンを追加
yupix Nov 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
POSTGRES_USER="postgres"
POSTGRES_PASSWORD="postgres"
POSTGRES_DB="postgres"
POSTGRES_HOST="localhost"
POSTGRES_PORT="5432"
DATABASE_URL="postgresql://db-user:db-pass@localhost:5432/db-name?schema=public"

S3_BUCKET_NAME="test"
S3_ACCESS_KEY="test"
S3_SECRET_KEY="test"
S3_REGION="us-west-1"
S3_ENDPOINT="https://s3.akarinext.org"
S3_PREFIX="*"

# PKCEを使用してください。CLIENT_SECRETは使用しません。認証方式はnoneになっています。
OIDC_CLIENT_ID=""
OIDC_ISSUER="https://example.com/OIDC-Provider-URL"
OIDC_REDIRECT_URIS="['https://example.com/redirect-URL1', 'https://example.com/redirect-URL2']"
OIDC_USERINFO_ENDPOINT=""
SESSION_SECRET="セッションシークレット"
4 changes: 3 additions & 1 deletion .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ jobs:
postgres:
image: postgres
env:
POSTGRES_PASSWORD: postgres
POSTGRES_PASSWORD: db-pass
POSTGRES_USER: db-user
POSTGRES_DB: db-name
options: >-
--health-cmd pg_isready
--health-interval 10s
Expand Down
121 changes: 69 additions & 52 deletions app/components/ArticleCard.tsx
Original file line number Diff line number Diff line change
@@ -1,57 +1,74 @@
import { InlineIcon } from "@iconify/react/dist/iconify.js";
import { NavLink } from "@remix-run/react";
import { cn } from "~/lib/utils";
import { InlineIcon } from '@iconify/react/dist/iconify.js';
import { NavLink } from '@remix-run/react';
import { cn } from '~/lib/utils';

export type ArticleCardProps = {
title: string;
emoji: string;
dateDisplay: string;
classes?: { root: string };
isTransitioning?: boolean;
}

export function ArticleCard({ title, emoji, dateDisplay, classes, isTransitioning }: ArticleCardProps) {
return (
<div className={cn("bg-white border rounded-xl flex flex-col justify-between", classes?.root)}>
<div className="flex items-center flex-col bg-primary py-8 rounded-t-xl">
<div className="flex items-center justify-center h-20 w-20 rounded-full bg-blue-100">
<InlineIcon
icon={`fluent-emoji-flat:${emoji}`}
className="h-20 w-20 bg-white p-2 rounded-lg"
style={
isTransitioning
? { viewTransitionName: 'blog-image' }
: undefined
}
/>
</div>
</div>
<div className="flex flex-col flex-grow p-4">
<h2 className="text-lg font-semibold text-gray-800" style={
isTransitioning
? { viewTransitionName: 'blog-title' }
: undefined
}>{title}</h2>
<div className="flex-grow"></div>
<p className="text-gray-600 pt-8 select-none">
{dateDisplay}
</p>
</div>
</div>
)
title: string;
emoji: string;
dateDisplay: string;
classes?: { root: string };
isTransitioning?: boolean;
};

export function ArticleCard({
title,
emoji,
dateDisplay,
classes,
isTransitioning,
}: ArticleCardProps) {
return (
<div
className={cn(
'bg-white border rounded-xl flex flex-col justify-between',
classes?.root,
)}
>
<div className="flex items-center flex-col bg-primary py-8 rounded-t-xl">
<div className="flex items-center justify-center h-20 w-20 rounded-full bg-blue-100">
<InlineIcon
icon={`fluent-emoji-flat:${emoji}`}
className="h-20 w-20 bg-white p-2 rounded-lg"
style={
isTransitioning ? { viewTransitionName: 'blog-image' } : undefined
}
/>
</div>
</div>
<div className="flex flex-col flex-grow p-4">
<h2
className="text-lg font-semibold text-gray-800"
style={
isTransitioning ? { viewTransitionName: 'blog-title' } : undefined
}
>
{title}
</h2>
<div className="flex-grow"></div>
<p className="text-gray-600 pt-8 select-none">{dateDisplay}</p>
</div>
</div>
);
}

export function ArticleCardWithLink({ title, emoji, dateDisplay, classes, slug }: ArticleCardProps & { slug: string }) {
return (
<NavLink
to={`/blog/${slug}`}
unstable_viewTransition
prefetch="intent"
>
{({ isTransitioning }) => (
<ArticleCard title={title} emoji={emoji} dateDisplay={dateDisplay} classes={classes} isTransitioning={isTransitioning} />
)}
</NavLink>
);
};
export function ArticleCardWithLink({
title,
emoji,
dateDisplay,
classes,
slug,
}: ArticleCardProps & { slug: string }) {
return (
<NavLink to={`/blog/${slug}`} unstable_viewTransition prefetch="intent">
{({ isTransitioning }) => (
<ArticleCard
title={title}
emoji={emoji}
dateDisplay={dateDisplay}
classes={classes}
isTransitioning={isTransitioning}
/>
)}
</NavLink>
);
}
43 changes: 21 additions & 22 deletions app/components/Avatar.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
import { cn } from "~/lib/utils";
import { cn } from '~/lib/utils';

export type AvatarProps = {
src: string;
alt: string;
size?: "xs" | "sm" | "md" | "lg";
rounded?: "full" | "md" | "sm" | "none";
}
src: string;
alt: string;
size?: 'xs' | 'sm' | 'md' | 'lg';
rounded?: 'full' | 'md' | 'sm' | 'none';
};

export const avatarSizes = {
xs: "w-8 h-8",
sm: "w-12 h-12",
md: "w-16 h-16",
lg: "w-24 h-24"
}
xs: 'w-8 h-8',
sm: 'w-12 h-12',
md: 'w-16 h-16',
lg: 'w-24 h-24',
};

export const avatarRoundeds = {
full: "rounded-full",
md: "rounded-md",
sm: "rounded-sm",
none: "rounded-none"
}
full: 'rounded-full',
md: 'rounded-md',
sm: 'rounded-sm',
none: 'rounded-none',
};

export function Avatar({src, alt, size, rounded}: AvatarProps) {
export function Avatar({ src, alt, size, rounded }: AvatarProps) {
const sizeClass = size ? avatarSizes[size] : avatarSizes.md;
const roundedClass = rounded ? avatarRoundeds[rounded] : avatarRoundeds.full;

const sizeClass = size ? avatarSizes[size] : avatarSizes.md
const roundedClass = rounded ? avatarRoundeds[rounded] : avatarRoundeds.full

return <img src={src} alt={alt} className={cn(sizeClass, roundedClass)} />
}
return <img src={src} alt={alt} className={cn(sizeClass, roundedClass)} />;
}
4 changes: 3 additions & 1 deletion app/components/MemberCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ export function MemberCard({ member }: MemberCardProps) {
</div>
<div className="flex gap-1 flex-row flex-wrap border-t pt-2 mt-2">
{member.roles.map((role, index) => (
<Badge key={index}>{role}</Badge>
<Badge key={index} className="select-none">
{role}
</Badge>
))}
</div>
</div>
Expand Down
87 changes: 18 additions & 69 deletions app/components/footer.tsx
Original file line number Diff line number Diff line change
@@ -1,78 +1,27 @@
import { Link } from '@remix-run/react';
import {
NavigationMenu,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuList,
navigationMenuTriggerStyle,
} from './ui/navigation-menu';
import type { TConfig } from '~/lib/config.server';
import type { PickType } from '~/lib/helper.server';
import { getSocialIcon } from '~/lib/utils';
import EasyTooltip from './Tooltip';

type Props = {
links: PickType<PickType<TConfig, 'footer'>, 'links'>;
};

export function Footer({ links }: Props) {
export function Footer() {
return (
<footer className="mt-16 bg-white p-4">
<div className="sm:flex block min-h-16 items-center sticky mb-4">
<NavigationMenu>
<NavigationMenuList>
<NavigationMenuItem className="text-2xl font-bold">
<NavigationMenuLink
className={navigationMenuTriggerStyle()}
asChild
>
<Link to="/" aria-label="トップページに移動する">
AkariNext
</Link>
</NavigationMenuLink>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>
<NavigationMenu>
<NavigationMenuList>
{links.map((link, index) =>
link.alt ? (
<EasyTooltip key={index} tooltip={link.alt}>
<NavigationMenuLink
className={navigationMenuTriggerStyle()}
asChild
>
<a
href={link.link}
target="_blank"
rel="noreferrer noopener"
aria-label={`${link.type} へ移動する`}
>
{getSocialIcon(link.type)}
</a>
</NavigationMenuLink>
</EasyTooltip>
) : (
<NavigationMenuLink
key={index}
className={navigationMenuTriggerStyle()}
asChild
<div className="m-auto" style={{ maxWidth: 'min(1200px, 90%)' }}>
<div className="sm:flex block min-h-16 justify-between items-center sticky mb-4">
AkariNext
<div className="border-l-2 border-blue-400 p-2">
<h4>LINKS</h4>
<ul>
<li className="relative">
<Link
to="/tos"
className='after:border-b after:border-blue-400 after:content-[""] after:absolute after:w-2 after:-left-2 after:top-1/2 pl-2'
>
<a
href={link.link}
target="_blank"
rel="noreferrer noopener"
aria-label={`${link.type} へ移動する`}
>
{getSocialIcon(link.type)}
</a>
</NavigationMenuLink>
),
)}
</NavigationMenuList>
</NavigationMenu>
利用規約
</Link>
</li>
</ul>
</div>
</div>
<div className="mt-4">&copy; 2024 AkariNext</div>
</div>
<div className="mt-4 px-3">&copy; 2024 AkariNext</div>
</footer>
);
}
Loading
Loading