Compare changes

Choose any two refs to compare.

Changed files
+236 -63
src
assets
styles
components
layouts
pages
+4 -1
package.json
··· 11 11 "@tailwindcss/vite": "^4.1.13", 12 12 "astro": "^5.13.7", 13 13 "nanoid": "^5.1.5", 14 + "quill": "^2.0.3", 14 15 "tailwindcss": "^4.1.13" 15 16 }, 16 17 "scripts": { ··· 25 26 "daisyui": "^5.1.10" 26 27 }, 27 28 "trustedDependencies": [ 28 - "@tailwindcss/oxide" 29 + "@tailwindcss/oxide", 30 + "esbuild", 31 + "sharp" 29 32 ] 30 33 }
+130
src/assets/styles/global.css
··· 36 36 @utility title { 37 37 font-family: var(--font-display); 38 38 font-size: var(--text-xl); 39 + } 40 + 41 + body { 42 + height: 100vh; 43 + font-family: var(--body); 44 + font-size: var(--step-0); 45 + line-height: 1.5; 46 + } 47 + 48 + h1 { 49 + font-size: 1.5em; 50 + font-weight: bold; 51 + } 52 + 53 + label { 54 + display: block; 55 + font-size: .8em; 56 + font-weight: bold; 57 + } 58 + 59 + input[type="text"], 60 + input[type="number"], 61 + input[type="email"], 62 + textarea { 63 + border: 1px var(--color-base-300) solid; 64 + border-radius: 2px; 65 + padding: 3px 5px; 66 + font-size: inherit; 67 + font-family: var(--sans); 68 + width: 100%; 69 + } 70 + 71 + .btn-primary, 72 + button[type="submit"], 73 + input[type="submit"], 74 + input[type="reset"] { 75 + background-color: var(--color-primary); 76 + color: var(--color-primary-content); 77 + border-radius: 4px; 78 + padding: 5px 10px; 79 + font-size: 1em; 80 + font-weight: bold; 81 + text-align: center; 82 + min-width: 150px; 83 + transition: 0.3s; 84 + position: relative; 85 + } 86 + 87 + .btn-primary:hover, 88 + button[type="submit"]:hover, 89 + input[type="submit"]:hover, 90 + input[type="reset"]:hover { 91 + background-color: color-mix(in srgb-linear, var(--color-primary), #000000 20%); 92 + } 93 + 94 + .btn-primary:active, 95 + button[type="submit"]:active, 96 + input[type="submit"]:active, 97 + input[type="reset"]:active { 98 + top: 1px; 99 + } 100 + 101 + .input-field { 102 + display: block; 103 + margin-bottom: 1em; 104 + } 105 + 106 + nav ul.menu { 107 + gap: 20px; 108 + align-items: center; 109 + } 110 + 111 + nav ul.menu form:hover { 112 + background-color: transparent; 113 + border-radius: none; 114 + } 115 + 116 + nav ul.menu .search-label { 117 + width: 1px; 118 + height: 1px; 119 + position: absolute; 120 + overflow: hidden; 121 + text-indent: -100px; 122 + } 123 + 124 + nav ul.menu a { 125 + padding-bottom: 5px; 126 + border-width: 0 0 5px 0; 127 + padding: 5px 0; 128 + border-color: transparent; 129 + border-style: solid; 130 + box-shadow: none; 131 + background-color: transparent; 132 + border-radius: 0; 133 + } 134 + 135 + nav ul.menu a:hover { 136 + border-width: 0 0 5px 0; 137 + border-color: var(--color-secondary); 138 + border-style: solid; 139 + } 140 + 141 + .ql-toolbar.ql-snow { 142 + border-color: var(--color-base-300) !important; 143 + border-radius: 2px 2px 0 0; 144 + } 145 + 146 + #content.ql-container.ql-snow { 147 + border-color: var(--color-base-300); 148 + border-radius: 0 0 2px 2px; 149 + } 150 + 151 + article.card { 152 + border: 1px var(--color-base-300) solid; 153 + border-radius: 5px; 154 + } 155 + 156 + article.card h2 { 157 + font-size: 1.1em; 158 + font-weight: bold; 159 + } 160 + 161 + article.card .author { 162 + font-size: .8em; 163 + font-weight: normal; 164 + font-style: italic; 165 + } 166 + 167 + article.card time { 168 + font-size: .8em; 39 169 }
+7 -2
src/components/Navbar.astro
··· 3 3 --- 4 4 <nav id="main-nav" class="navbar bg-base-100"> 5 5 <div class="flex-1"> 6 - <a href="/" class="btn btn-ghost font-display text-xl">Home</a> 6 + <a href="/" class="font-display text-xl">Home</a> 7 7 </div> 8 8 <div class="flex-none"> 9 9 <ul class="menu menu-horizontal px-1"> 10 - <li><a href="/search">Search</a></li> 10 + <li> 11 + <form method="get"> 12 + <label class="label search-label" for="work-search">Search</label> 13 + <input class="input" type="search" name="workSearch" id="work-search" placeholder="Search" /> 14 + </form> 15 + </li> 11 16 <li><a href="/works">Works</a></li> 12 17 {loggedInUser 13 18 ? <>
+1 -1
src/layouts/Layout.astro
··· 37 37 <slot /> 38 38 </div> 39 39 40 - <footer class="footer sm:footer-horizontal footer-center bg-base-300 text-base-content mt-auto p-5"> 40 + <footer class="footer sm:footer-horizontal footer-center bg-base-300 text-base-content mt-5 p-5"> 41 41 copyright or something ig 42 42 </footer> 43 43 </body>
+1 -1
src/pages/index.astro
··· 17 17 <button>logout</button> 18 18 </form> 19 19 </> 20 - : <a href="/login">login</a>} 20 + : <a href="/login" class="btn">login</a>} 21 21 </Layout>
+74 -48
src/pages/works/add.astro
··· 1 1 --- 2 2 import Layout from "@/layouts/Layout.astro"; 3 3 import { actions, isInputError } from "astro:actions"; 4 + import "quill/dist/quill.core.css"; 5 + import "quill/dist/quill.snow.css"; 4 6 5 7 const loggedInUser = Astro.locals.loggedInUser; 6 8 ··· 21 23 <h1>Add a new work</h1> 22 24 23 25 <form action={actions.worksActions.addWork} method="post"> 24 - <label for="title">title</label> 25 - <input 26 - type="text" 27 - name="title" 28 - id="title" 29 - aria-describedby="title-error" 30 - required 31 - transition:persist 32 - /> 33 - {errors.title && ( 34 - <div id="title-error"> 35 - {errors.title} 36 - </div> 37 - )} 26 + <div class="input-field"> 27 + <label for="title">Title</label> 28 + <input 29 + type="text" 30 + name="title" 31 + id="title" 32 + aria-describedby="title-error" 33 + required 34 + transition:persist 35 + /> 36 + {errors.title && ( 37 + <div id="title-error"> 38 + {errors.title} 39 + </div> 40 + )} 41 + </div> 38 42 39 - <label for="tags">add tags</label> 40 - <input 41 - type="text" 42 - list="tags-list" 43 - name="tags" 44 - id="tags" 45 - aria-describedby="tags-error" 46 - transition:persist 47 - /> 48 - <!-- could be cool to fetch tags from a tags server or smth? idk --> 49 - <datalist id="tags-list"> 50 - <option value="test">here</option> 51 - <option value="tag2">another</option> 52 - <option value="tag3">try them all!</option> 53 - </datalist> 54 - {errors.tags && ( 55 - <div id="tags-error"> 56 - {errors.tags} 57 - </div> 58 - )} 43 + <div class="input-field"> 44 + <label for="tags">Add Tags</label> 45 + <input 46 + type="text" 47 + list="tags-list" 48 + name="tags" 49 + id="tags" 50 + aria-describedby="tags-error" 51 + transition:persist 52 + /> 53 + <!-- could be cool to fetch tags from a tags server or smth? idk --> 54 + <!-- maybe from labelers the instance is subscribed to? - @veryroundbird.house --> 55 + <datalist id="tags-list"> 56 + <option value="test">here</option> 57 + <option value="tag2">another</option> 58 + <option value="tag3">try them all!</option> 59 + </datalist> 60 + {errors.tags && ( 61 + <div id="tags-error"> 62 + {errors.tags} 63 + </div> 64 + )} 65 + </div> 59 66 60 - <label for="content">body</label> 61 - <!-- replace this with a rich text editor / code editor later --> 62 - <textarea name="content" id="content" aria-describedby="content-error" transition:persist></textarea> 63 - {errors.content && ( 64 - <div id="content-error"> 65 - {errors.content} 66 - </div> 67 - )} 68 - 69 - <label for="publish">Publish to your PDS?</label> 70 - <input type="checkbox" name="publish" id="publish" /> 71 - 72 - <button>submit</button> 67 + <div class="input-field"> 68 + <label for="content">Work Text</label> 69 + <div id="content" aria-describedby="content-error" transition:persist rows="50"></div> 70 + {errors.content && ( 71 + <div id="content-error"> 72 + {errors.content} 73 + </div> 74 + )} 75 + </div> 76 + <div class="input-field"> 77 + <label for="publish"><input type="checkbox" name="publish" id="publish" /> Publish to your PDS?</label> 78 + </div> 79 + <div class="input-field"> 80 + <button type="submit" class="btn-primary">Submit</button> 81 + </div> 73 82 </form> 74 83 75 84 {result?.error && ( ··· 78 87 </div> 79 88 )} 80 89 </main> 81 - </Layout> 90 + </Layout> 91 + 92 + <script> 93 + import Quill from "quill"; 94 + 95 + const quill = new Quill('#content', { 96 + theme: 'snow', 97 + modules: { 98 + syntax: true 99 + } 100 + }); 101 + </script> 102 + 103 + <style> 104 + #content { 105 + min-height: 50vh; 106 + } 107 + </style>
+19 -10
src/pages/works/index.astro
··· 22 22 {works.map(async ({ Works, Users }) => ( 23 23 <article class="card rounded-box shadow p-5"> 24 24 <header> 25 - <div class="flex items-center justify-between"> 25 + <div class="flex items-top justify-between"> 26 26 <hgroup class="flex-1"> 27 27 <h2 class="card-title"> 28 28 <a href={`/works/${Works.slug}`}>{Works.title}</a> 29 29 </h2> 30 - <h3> 30 + <p class="author"> 31 31 {Users.nickname 32 32 ? Users.nickname 33 33 : await didToHandle(Users.userDid)} 34 - </h3> 34 + </p> 35 35 </hgroup> 36 36 <time datetime={Works.createdAt.toISOString()}> 37 37 {Works.createdAt.toLocaleDateString()} 38 38 </time> 39 39 </div> 40 - {JSON.stringify(Works.tags)} 41 - {/* <ul class="flex flex-wrap gap-1.5"> 42 - {(Works.tags as Tag[]).map((tag: Tag) => ( 43 - <li><a class="tag" href={tag.url}>{tag.label}</a></li> 44 - ))} 45 - </ul> */} 40 + {Array.isArray(Works.tags) && 41 + <ul class="flex flex-wrap gap-1.5"> 42 + {(Works.tags as Tag[]).map((tag: Tag) => ( 43 + <li><a class="tag" href={tag.url}>{tag.label}</a></li> 44 + ))} 45 + </ul> } 46 46 </header> 47 47 48 48 <div class="card-body prose lg:prose-xl"> ··· 57 57 @reference "../../assets/styles/global.css"; 58 58 59 59 .tag { 60 - @apply btn btn-accent; 60 + @apply btn btn-accent; 61 + padding: 3px 12px; 62 + border-radius: 12px; 63 + height: auto; 64 + line-height: 1; 65 + } 66 + 67 + .card-body { 68 + padding-left: 0; 69 + padding-right: 0; 61 70 } 62 71 </style>